Merge pull request #9863 from filecoin-project/feat/eth-gateway-api
feat: eth gateway api
This commit is contained in:
commit
32615ecbd3
@ -13,6 +13,7 @@ import (
|
|||||||
|
|
||||||
apitypes "github.com/filecoin-project/lotus/api/types"
|
apitypes "github.com/filecoin-project/lotus/api/types"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MODIFYING THE API INTERFACE
|
// MODIFYING THE API INTERFACE
|
||||||
@ -69,4 +70,38 @@ type Gateway interface {
|
|||||||
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
WalletBalance(context.Context, address.Address) (types.BigInt, error)
|
||||||
Version(context.Context) (APIVersion, error)
|
Version(context.Context) (APIVersion, error)
|
||||||
Discover(context.Context) (apitypes.OpenRPCDocument, 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)
|
||||||
}
|
}
|
||||||
|
44
api/eth_aliases.go
Normal file
44
api/eth_aliases.go
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import apitypes "github.com/filecoin-project/lotus/api/types"
|
||||||
|
|
||||||
|
func CreateEthRPCAliases(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")
|
||||||
|
}
|
429
api/proxy_gen.go
429
api/proxy_gen.go
@ -619,6 +619,68 @@ type GatewayStruct struct {
|
|||||||
|
|
||||||
Discover func(p0 context.Context) (apitypes.OpenRPCDocument, error) ``
|
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) ``
|
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) ``
|
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) ``
|
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) ``
|
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) ``
|
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
|
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) {
|
func (s *GatewayStruct) GasEstimateMessageGas(p0 context.Context, p1 *types.Message, p2 *MessageSendSpec, p3 types.TipSetKey) (*types.Message, error) {
|
||||||
if s.Internal.GasEstimateMessageGas == nil {
|
if s.Internal.GasEstimateMessageGas == nil {
|
||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
@ -4075,6 +4482,28 @@ func (s *GatewayStub) MsigGetVestingSchedule(p0 context.Context, p1 address.Addr
|
|||||||
return *new(MsigVesting), ErrNotSupported
|
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) {
|
func (s *GatewayStruct) StateAccountKey(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (address.Address, error) {
|
||||||
if s.Internal.StateAccountKey == nil {
|
if s.Internal.StateAccountKey == nil {
|
||||||
return *new(address.Address), ErrNotSupported
|
return *new(address.Address), ErrNotSupported
|
||||||
|
5
api/types/rpc.go
Normal file
5
api/types/rpc.go
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
package apitypes
|
||||||
|
|
||||||
|
type Aliaser interface {
|
||||||
|
AliasMethod(alias, original string)
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -25,6 +25,10 @@ type perConnLimiterKeyType string
|
|||||||
|
|
||||||
const perConnLimiterKey perConnLimiterKeyType = "limiter"
|
const perConnLimiterKey perConnLimiterKeyType = "limiter"
|
||||||
|
|
||||||
|
type filterTrackerKeyType string
|
||||||
|
|
||||||
|
const filterTrackerKey filterTrackerKeyType = "filterTracker"
|
||||||
|
|
||||||
// Handler returns a gateway http.Handler, to be mounted as-is on the server.
|
// Handler returns a gateway http.Handler, to be mounted as-is on the server.
|
||||||
func Handler(gwapi lapi.Gateway, api lapi.FullNode, rateLimit int64, connPerMinute int64, opts ...jsonrpc.ServerOption) (http.Handler, error) {
|
func Handler(gwapi lapi.Gateway, api lapi.FullNode, rateLimit int64, connPerMinute int64, opts ...jsonrpc.ServerOption) (http.Handler, error) {
|
||||||
m := mux.NewRouter()
|
m := mux.NewRouter()
|
||||||
@ -34,6 +38,8 @@ func Handler(gwapi lapi.Gateway, api lapi.FullNode, rateLimit int64, connPerMinu
|
|||||||
rpcServer.Register("Filecoin", hnd)
|
rpcServer.Register("Filecoin", hnd)
|
||||||
rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover")
|
rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover")
|
||||||
|
|
||||||
|
lapi.CreateEthRPCAliases(rpcServer)
|
||||||
|
|
||||||
m.Handle(path, rpcServer)
|
m.Handle(path, rpcServer)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +87,12 @@ type RateLimiterHandler struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (h RateLimiterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h RateLimiterHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
r2 := r.WithContext(context.WithValue(r.Context(), perConnLimiterKey, h.limiter))
|
r = r.WithContext(context.WithValue(r.Context(), perConnLimiterKey, h.limiter))
|
||||||
h.handler.ServeHTTP(w, r2)
|
|
||||||
|
// also add a filter tracker to the context
|
||||||
|
r = r.WithContext(context.WithValue(r.Context(), filterTrackerKey, newFilterTracker()))
|
||||||
|
|
||||||
|
h.handler.ServeHTTP(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
// this blocks new connections if there have already been too many.
|
// this blocks new connections if there have already been too many.
|
||||||
|
499
gateway/node.go
499
gateway/node.go
@ -9,21 +9,18 @@ import (
|
|||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"go.opencensus.io/stats"
|
"go.opencensus.io/stats"
|
||||||
"golang.org/x/time/rate"
|
"golang.org/x/time/rate"
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/filecoin-project/go-bitfield"
|
"github.com/filecoin-project/go-bitfield"
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/go-state-types/crypto"
|
|
||||||
"github.com/filecoin-project/go-state-types/dline"
|
"github.com/filecoin-project/go-state-types/dline"
|
||||||
"github.com/filecoin-project/go-state-types/network"
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"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/build"
|
||||||
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
"github.com/filecoin-project/lotus/chain/actors/builtin/miner"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/lib/sigs"
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||||
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
_ "github.com/filecoin-project/lotus/lib/sigs/bls"
|
||||||
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
|
_ "github.com/filecoin-project/lotus/lib/sigs/delegated"
|
||||||
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
_ "github.com/filecoin-project/lotus/lib/sigs/secp"
|
||||||
@ -88,7 +85,40 @@ type TargetAPI interface {
|
|||||||
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
StateSectorGetInfo(ctx context.Context, maddr address.Address, n abi.SectorNumber, tsk types.TipSetKey) (*miner.SectorOnChainInfo, error)
|
||||||
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
StateVerifiedClientStatus(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*abi.StoragePower, error)
|
||||||
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error)
|
StateVMCirculatingSupplyInternal(context.Context, types.TipSetKey) (api.CirculatingSupply, error)
|
||||||
WalletBalance(context.Context, address.Address) (types.BigInt, error) //perm:read
|
WalletBalance(context.Context, address.Address) (types.BigInt, 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) (*api.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)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ TargetAPI = *new(api.FullNode) // gateway depends on latest
|
var _ TargetAPI = *new(api.FullNode) // gateway depends on latest
|
||||||
@ -184,462 +214,3 @@ func (gw *Node) limit(ctx context.Context, tokens int) error {
|
|||||||
}
|
}
|
||||||
return nil
|
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)
|
|
||||||
}
|
|
||||||
|
481
gateway/proxy_eth.go
Normal file
481
gateway/proxy_eth.go
Normal file
@ -0,0 +1,481 @@
|
|||||||
|
package gateway
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
|
"github.com/filecoin-project/go-state-types/big"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/chain/types/ethtypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (gw *Node) EthAccounts(ctx context.Context) ([]ethtypes.EthAddress, error) {
|
||||||
|
// gateway provides public API, so it can't hold user accounts
|
||||||
|
return []ethtypes.EthAddress{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthBlockNumber(ctx context.Context) (ethtypes.EthUint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthBlockNumber(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetBlockTransactionCountByNumber(ctx context.Context, blkNum ethtypes.EthUint64) (ethtypes.EthUint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
head, err := gw.target.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
if err := gw.checkTipsetHeight(head, abi.ChainEpoch(blkNum)); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetBlockTransactionCountByNumber(ctx, blkNum)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) tskByEthHash(ctx context.Context, blkHash ethtypes.EthHash) (types.TipSetKey, error) {
|
||||||
|
tskCid := blkHash.ToCid()
|
||||||
|
tskBlk, err := gw.target.ChainReadObj(ctx, tskCid)
|
||||||
|
if err != nil {
|
||||||
|
return types.EmptyTSK, err
|
||||||
|
}
|
||||||
|
tsk := new(types.TipSetKey)
|
||||||
|
if err := tsk.UnmarshalCBOR(bytes.NewReader(tskBlk)); err != nil {
|
||||||
|
return types.EmptyTSK, xerrors.Errorf("cannot unmarshal block into tipset key: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return *tsk, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) checkBlkHash(ctx context.Context, blkHash ethtypes.EthHash) error {
|
||||||
|
tsk, err := gw.tskByEthHash(ctx, blkHash)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.checkTipsetKey(ctx, tsk)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) checkBlkParam(ctx context.Context, blkParam string) error {
|
||||||
|
if blkParam == "earliest" {
|
||||||
|
// also not supported in node impl
|
||||||
|
return fmt.Errorf("block param \"earliest\" is not supported")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch blkParam {
|
||||||
|
case "pending", "latest":
|
||||||
|
// those will be recent enough, so we don't need to check
|
||||||
|
return nil
|
||||||
|
default:
|
||||||
|
var num ethtypes.EthUint64
|
||||||
|
err := num.UnmarshalJSON([]byte(`"` + blkParam + `"`))
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("cannot parse block number: %v", err)
|
||||||
|
}
|
||||||
|
head, err := gw.target.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := gw.checkTipsetHeight(head, abi.ChainEpoch(num)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetBlockTransactionCountByHash(ctx context.Context, blkHash ethtypes.EthHash) (ethtypes.EthUint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkHash(ctx, blkHash); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetBlockTransactionCountByHash(ctx, blkHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetBlockByHash(ctx context.Context, blkHash ethtypes.EthHash, fullTxInfo bool) (ethtypes.EthBlock, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthBlock{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkHash(ctx, blkHash); err != nil {
|
||||||
|
return ethtypes.EthBlock{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetBlockByHash(ctx, blkHash, fullTxInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetBlockByNumber(ctx context.Context, blkNum string, fullTxInfo bool) (ethtypes.EthBlock, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthBlock{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkParam(ctx, blkNum); err != nil {
|
||||||
|
return ethtypes.EthBlock{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetBlockByNumber(ctx, blkNum, fullTxInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetTransactionByHash(ctx context.Context, txHash *ethtypes.EthHash) (*ethtypes.EthTx, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetTransactionByHash(ctx, txHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetTransactionCount(ctx context.Context, sender ethtypes.EthAddress, blkOpt string) (ethtypes.EthUint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkParam(ctx, blkOpt); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetTransactionCount(ctx, sender, blkOpt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetTransactionReceipt(ctx context.Context, txHash ethtypes.EthHash) (*api.EthTxReceipt, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetTransactionReceipt(ctx, txHash)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetTransactionByBlockHashAndIndex(ctx context.Context, blkHash ethtypes.EthHash, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkHash(ctx, blkHash); err != nil {
|
||||||
|
return ethtypes.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetTransactionByBlockHashAndIndex(ctx, blkHash, txIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetTransactionByBlockNumberAndIndex(ctx context.Context, blkNum ethtypes.EthUint64, txIndex ethtypes.EthUint64) (ethtypes.EthTx, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
head, err := gw.target.ChainHead(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return ethtypes.EthTx{}, err
|
||||||
|
}
|
||||||
|
if err := gw.checkTipsetHeight(head, abi.ChainEpoch(blkNum)); err != nil {
|
||||||
|
return ethtypes.EthTx{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetTransactionByBlockNumberAndIndex(ctx, blkNum, txIndex)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetCode(ctx context.Context, address ethtypes.EthAddress, blkOpt string) (ethtypes.EthBytes, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkParam(ctx, blkOpt); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetCode(ctx, address, blkOpt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetStorageAt(ctx context.Context, address ethtypes.EthAddress, position ethtypes.EthBytes, blkParam string) (ethtypes.EthBytes, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkParam(ctx, blkParam); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetStorageAt(ctx, address, position, blkParam)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetBalance(ctx context.Context, address ethtypes.EthAddress, blkParam string) (ethtypes.EthBigInt, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthBigInt(big.Zero()), err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkParam(ctx, blkParam); err != nil {
|
||||||
|
return ethtypes.EthBigInt(big.Zero()), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetBalance(ctx, address, blkParam)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthChainId(ctx context.Context) (ethtypes.EthUint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthChainId(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) NetVersion(ctx context.Context) (string, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.NetVersion(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) NetListening(ctx context.Context) (bool, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.NetListening(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthProtocolVersion(ctx context.Context) (ethtypes.EthUint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthProtocolVersion(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGasPrice(ctx context.Context) (ethtypes.EthBigInt, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthBigInt(big.Zero()), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGasPrice(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
var EthFeeHistoryMaxBlockCount = 128 // this seems to be expensive; todo: figure out what is a good number that works with everything
|
||||||
|
|
||||||
|
func (gw *Node) EthFeeHistory(ctx context.Context, blkCount ethtypes.EthUint64, newestBlk string, rewardPercentiles []float64) (ethtypes.EthFeeHistory, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthFeeHistory{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkParam(ctx, newestBlk); err != nil {
|
||||||
|
return ethtypes.EthFeeHistory{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if blkCount > ethtypes.EthUint64(EthFeeHistoryMaxBlockCount) {
|
||||||
|
return ethtypes.EthFeeHistory{}, fmt.Errorf("block count too high")
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthFeeHistory(ctx, blkCount, newestBlk, rewardPercentiles)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthMaxPriorityFeePerGas(ctx context.Context) (ethtypes.EthBigInt, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthBigInt(big.Zero()), err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthMaxPriorityFeePerGas(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthEstimateGas(ctx context.Context, tx ethtypes.EthCall) (ethtypes.EthUint64, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo limit gas? to what?
|
||||||
|
return gw.target.EthEstimateGas(ctx, tx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthCall(ctx context.Context, tx ethtypes.EthCall, blkParam string) (ethtypes.EthBytes, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gw.checkBlkParam(ctx, blkParam); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// todo limit gas? to what?
|
||||||
|
return gw.target.EthCall(ctx, tx, blkParam)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthSendRawTransaction(ctx context.Context, rawTx ethtypes.EthBytes) (ethtypes.EthHash, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthHash{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthSendRawTransaction(ctx, rawTx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetLogs(ctx context.Context, filter *ethtypes.EthFilterSpec) (*ethtypes.EthFilterResult, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if filter.FromBlock != nil {
|
||||||
|
if err := gw.checkBlkParam(ctx, *filter.FromBlock); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if filter.ToBlock != nil {
|
||||||
|
if err := gw.checkBlkParam(ctx, *filter.ToBlock); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if filter.BlockHash != nil {
|
||||||
|
if err := gw.checkBlkHash(ctx, *filter.BlockHash); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetLogs(ctx, filter)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FILTERS: Those are stateful.. figure out how to properly either bind them to users, or time out? */
|
||||||
|
|
||||||
|
func (gw *Node) EthGetFilterChanges(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ft := filterTrackerFromContext(ctx)
|
||||||
|
ft.lk.Lock()
|
||||||
|
_, ok := ft.userFilters[id]
|
||||||
|
ft.lk.Unlock()
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetFilterChanges(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthGetFilterLogs(ctx context.Context, id ethtypes.EthFilterID) (*ethtypes.EthFilterResult, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ft := filterTrackerFromContext(ctx)
|
||||||
|
ft.lk.Lock()
|
||||||
|
_, ok := ft.userFilters[id]
|
||||||
|
ft.lk.Unlock()
|
||||||
|
|
||||||
|
if !ok {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return gw.target.EthGetFilterLogs(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthNewFilter(ctx context.Context, filter *ethtypes.EthFilterSpec) (ethtypes.EthFilterID, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthFilterID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return addUserFilterLimited(ctx, func() (ethtypes.EthFilterID, error) {
|
||||||
|
return gw.target.EthNewFilter(ctx, filter)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthNewBlockFilter(ctx context.Context) (ethtypes.EthFilterID, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthFilterID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return addUserFilterLimited(ctx, func() (ethtypes.EthFilterID, error) {
|
||||||
|
return gw.target.EthNewBlockFilter(ctx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthNewPendingTransactionFilter(ctx context.Context) (ethtypes.EthFilterID, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return ethtypes.EthFilterID{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return addUserFilterLimited(ctx, func() (ethtypes.EthFilterID, error) {
|
||||||
|
return gw.target.EthNewPendingTransactionFilter(ctx)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthUninstallFilter(ctx context.Context, id ethtypes.EthFilterID) (bool, error) {
|
||||||
|
if err := gw.limit(ctx, stateRateLimitTokens); err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the filter belongs to this connection
|
||||||
|
ft := filterTrackerFromContext(ctx)
|
||||||
|
ft.lk.Lock()
|
||||||
|
defer ft.lk.Unlock()
|
||||||
|
|
||||||
|
if _, ok := ft.userFilters[id]; !ok {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
ok, err := gw.target.EthUninstallFilter(ctx, id)
|
||||||
|
if err != nil {
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
|
||||||
|
delete(ft.userFilters, id)
|
||||||
|
return ok, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthSubscribe(ctx context.Context, eventType string, params *ethtypes.EthSubscriptionParams) (<-chan ethtypes.EthSubscriptionResponse, error) {
|
||||||
|
return nil, xerrors.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gw *Node) EthUnsubscribe(ctx context.Context, id ethtypes.EthSubscriptionID) (bool, error) {
|
||||||
|
return false, xerrors.Errorf("not implemented")
|
||||||
|
}
|
||||||
|
|
||||||
|
var EthMaxFiltersPerConn = 16 // todo make this configurable
|
||||||
|
|
||||||
|
func addUserFilterLimited(ctx context.Context, cb func() (ethtypes.EthFilterID, error)) (ethtypes.EthFilterID, error) {
|
||||||
|
ft := filterTrackerFromContext(ctx)
|
||||||
|
ft.lk.Lock()
|
||||||
|
defer ft.lk.Unlock()
|
||||||
|
|
||||||
|
if len(ft.userFilters) >= EthMaxFiltersPerConn {
|
||||||
|
return ethtypes.EthFilterID{}, fmt.Errorf("too many filters")
|
||||||
|
}
|
||||||
|
|
||||||
|
id, err := cb()
|
||||||
|
if err != nil {
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
|
||||||
|
ft.userFilters[id] = time.Now()
|
||||||
|
|
||||||
|
return id, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterTrackerFromContext(ctx context.Context) *filterTracker {
|
||||||
|
return ctx.Value(filterTrackerKey).(*filterTracker)
|
||||||
|
}
|
||||||
|
|
||||||
|
type filterTracker struct {
|
||||||
|
lk sync.Mutex
|
||||||
|
|
||||||
|
userFilters map[ethtypes.EthFilterID]time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
// called per request (ws connection)
|
||||||
|
func newFilterTracker() *filterTracker {
|
||||||
|
return &filterTracker{
|
||||||
|
userFilters: make(map[ethtypes.EthFilterID]time.Time),
|
||||||
|
}
|
||||||
|
}
|
482
gateway/proxy_fil.go
Normal file
482
gateway/proxy_fil.go
Normal file
@ -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)
|
||||||
|
}
|
@ -152,8 +152,8 @@ var ChainNode = Options(
|
|||||||
Override(new(full.MpoolModuleAPI), From(new(api.Gateway))),
|
Override(new(full.MpoolModuleAPI), From(new(api.Gateway))),
|
||||||
Override(new(full.StateModuleAPI), From(new(api.Gateway))),
|
Override(new(full.StateModuleAPI), From(new(api.Gateway))),
|
||||||
Override(new(stmgr.StateManagerAPI), rpcstmgr.NewRPCStateManager),
|
Override(new(stmgr.StateManagerAPI), rpcstmgr.NewRPCStateManager),
|
||||||
// this to make tests pass, but we should consider actually implementing it in the gateway
|
Override(new(full.EthModuleAPI), From(new(api.Gateway))),
|
||||||
Override(new(full.EthModuleAPI), new(full.EthModuleDummy)),
|
Override(new(full.EthEventAPI), From(new(api.Gateway))),
|
||||||
),
|
),
|
||||||
|
|
||||||
// Full node API / service startup
|
// Full node API / service startup
|
||||||
@ -259,7 +259,8 @@ func ConfigFullNode(c interface{}) Option {
|
|||||||
|
|
||||||
// Actor event filtering support
|
// Actor event filtering support
|
||||||
Override(new(events.EventAPI), From(new(modules.EventAPI))),
|
Override(new(events.EventAPI), From(new(modules.EventAPI))),
|
||||||
Override(new(full.EthEventAPI), modules.EthEventAPI(cfg.ActorEvent)),
|
// in lite-mode Eth event api is provided by gateway
|
||||||
|
ApplyIf(isFullNode, Override(new(full.EthEventAPI), modules.EthEventAPI(cfg.ActorEvent))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
40
node/rpc.go
40
node/rpc.go
@ -79,44 +79,7 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server
|
|||||||
rpcServer.Register("Filecoin", hnd)
|
rpcServer.Register("Filecoin", hnd)
|
||||||
rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover")
|
rpcServer.AliasMethod("rpc.discover", "Filecoin.Discover")
|
||||||
|
|
||||||
// TODO: use reflect to automatically register all the eth aliases
|
api.CreateEthRPCAliases(rpcServer)
|
||||||
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")
|
|
||||||
|
|
||||||
var handler http.Handler = rpcServer
|
var handler http.Handler = rpcServer
|
||||||
if permissioned {
|
if permissioned {
|
||||||
@ -144,7 +107,6 @@ func FullNodeHandler(a v1api.FullNode, permissioned bool, opts ...jsonrpc.Server
|
|||||||
Next: handleImportFunc,
|
Next: handleImportFunc,
|
||||||
}
|
}
|
||||||
m.Handle("/rest/v0/import", importAH)
|
m.Handle("/rest/v0/import", importAH)
|
||||||
|
|
||||||
exportAH := &auth.Handler{
|
exportAH := &auth.Handler{
|
||||||
Verify: a.AuthVerify,
|
Verify: a.AuthVerify,
|
||||||
Next: handleExportFunc,
|
Next: handleExportFunc,
|
||||||
|
Loading…
Reference in New Issue
Block a user