|
|
|
@ -62,7 +62,7 @@ func ClientWithTag(chainClient ClientInterface, tag, groupTag string) ClientInte
|
|
|
|
|
|
|
|
|
|
type ClientWithFallback struct {
|
|
|
|
|
ChainID uint64
|
|
|
|
|
ethClients []ethclient.RPSLimitedEthClientInterface
|
|
|
|
|
ethClients []ethclient.EthClientInterface
|
|
|
|
|
circuitbreaker *circuitbreaker.CircuitBreaker
|
|
|
|
|
providersHealthManager *healthmanager.ProvidersHealthManager
|
|
|
|
|
|
|
|
|
@ -108,7 +108,7 @@ var propagateErrors = []error{
|
|
|
|
|
bind.ErrNoCode,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewClient(ethClients []ethclient.RPSLimitedEthClientInterface, chainID uint64, providersHealthManager *healthmanager.ProvidersHealthManager) *ClientWithFallback {
|
|
|
|
|
func NewClient(ethClients []ethclient.EthClientInterface, chainID uint64, providersHealthManager *healthmanager.ProvidersHealthManager) *ClientWithFallback {
|
|
|
|
|
cbConfig := circuitbreaker.Config{
|
|
|
|
|
Timeout: 20000,
|
|
|
|
|
MaxConcurrentRequests: 100,
|
|
|
|
@ -178,7 +178,7 @@ func (c *ClientWithFallback) IsConnected() bool {
|
|
|
|
|
return c.isConnected.Load()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (c *ClientWithFallback) makeCall(ctx context.Context, ethClients []ethclient.RPSLimitedEthClientInterface, f func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error)) (interface{}, error) {
|
|
|
|
|
func (c *ClientWithFallback) makeCall(ctx context.Context, ethClients []ethclient.EthClientInterface, f func(client ethclient.EthClientInterface) (interface{}, error)) (interface{}, error) {
|
|
|
|
|
c.LastCheckedAt = time.Now().Unix()
|
|
|
|
|
|
|
|
|
|
cmd := circuitbreaker.NewCommand(ctx, nil)
|
|
|
|
@ -213,7 +213,7 @@ func (c *ClientWithFallback) BlockByHash(ctx context.Context, hash common.Hash)
|
|
|
|
|
rpcstats.CountCallWithTag("eth_BlockByHash", c.tag)
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.BlockByHash(ctx, hash)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -230,7 +230,7 @@ func (c *ClientWithFallback) BlockByHash(ctx context.Context, hash common.Hash)
|
|
|
|
|
func (c *ClientWithFallback) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) {
|
|
|
|
|
rpcstats.CountCallWithTag("eth_BlockByNumber", c.tag)
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.BlockByNumber(ctx, number)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -248,7 +248,7 @@ func (c *ClientWithFallback) BlockNumber(ctx context.Context) (uint64, error) {
|
|
|
|
|
rpcstats.CountCallWithTag("eth_BlockNumber", c.tag)
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.BlockNumber(ctx)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -265,7 +265,7 @@ func (c *ClientWithFallback) BlockNumber(ctx context.Context) (uint64, error) {
|
|
|
|
|
func (c *ClientWithFallback) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) {
|
|
|
|
|
rpcstats.CountCallWithTag("eth_HeaderByHash", c.tag)
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.HeaderByHash(ctx, hash)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -282,7 +282,7 @@ func (c *ClientWithFallback) HeaderByHash(ctx context.Context, hash common.Hash)
|
|
|
|
|
func (c *ClientWithFallback) HeaderByNumber(ctx context.Context, number *big.Int) (*types.Header, error) {
|
|
|
|
|
rpcstats.CountCallWithTag("eth_HeaderByNumber", c.tag)
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.HeaderByNumber(ctx, number)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -300,7 +300,7 @@ func (c *ClientWithFallback) TransactionByHash(ctx context.Context, hash common.
|
|
|
|
|
rpcstats.CountCallWithTag("eth_TransactionByHash", c.tag)
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
tx, isPending, err := client.TransactionByHash(ctx, hash)
|
|
|
|
|
return []any{tx, isPending}, err
|
|
|
|
|
},
|
|
|
|
@ -320,7 +320,7 @@ func (c *ClientWithFallback) TransactionSender(ctx context.Context, tx *types.Tr
|
|
|
|
|
rpcstats.CountCall("eth_TransactionSender")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.TransactionSender(ctx, tx, block, index)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -334,7 +334,7 @@ func (c *ClientWithFallback) TransactionReceipt(ctx context.Context, txHash comm
|
|
|
|
|
rpcstats.CountCall("eth_TransactionReceipt")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.TransactionReceipt(ctx, txHash)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -352,7 +352,7 @@ func (c *ClientWithFallback) SyncProgress(ctx context.Context) (*ethereum.SyncPr
|
|
|
|
|
rpcstats.CountCall("eth_SyncProgress")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.SyncProgress(ctx)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -374,7 +374,7 @@ func (c *ClientWithFallback) BalanceAt(ctx context.Context, account common.Addre
|
|
|
|
|
rpcstats.CountCallWithTag("eth_BalanceAt", c.tag)
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.BalanceAt(ctx, account, blockNumber)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -392,7 +392,7 @@ func (c *ClientWithFallback) StorageAt(ctx context.Context, account common.Addre
|
|
|
|
|
rpcstats.CountCall("eth_StorageAt")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.StorageAt(ctx, account, key, blockNumber)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -410,7 +410,7 @@ func (c *ClientWithFallback) CodeAt(ctx context.Context, account common.Address,
|
|
|
|
|
rpcstats.CountCall("eth_CodeAt")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.CodeAt(ctx, account, blockNumber)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -428,7 +428,7 @@ func (c *ClientWithFallback) NonceAt(ctx context.Context, account common.Address
|
|
|
|
|
rpcstats.CountCallWithTag("eth_NonceAt", c.tag)
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.NonceAt(ctx, account, blockNumber)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -446,13 +446,13 @@ func (c *ClientWithFallback) FilterLogs(ctx context.Context, q ethereum.FilterQu
|
|
|
|
|
rpcstats.CountCallWithTag("eth_FilterLogs", c.tag)
|
|
|
|
|
|
|
|
|
|
// Override providers name to use a separate circuit for this command as it more often fails due to rate limiting
|
|
|
|
|
ethClients := make([]ethclient.RPSLimitedEthClientInterface, len(c.ethClients))
|
|
|
|
|
ethClients := make([]ethclient.EthClientInterface, len(c.ethClients))
|
|
|
|
|
for i, client := range c.ethClients {
|
|
|
|
|
ethClients[i] = client.CopyWithName(client.GetName() + "_FilterLogs")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.FilterLogs(ctx, q)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -471,7 +471,7 @@ func (c *ClientWithFallback) SubscribeFilterLogs(ctx context.Context, q ethereum
|
|
|
|
|
rpcstats.CountCall("eth_SubscribeFilterLogs")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.SubscribeFilterLogs(ctx, q, ch)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -489,7 +489,7 @@ func (c *ClientWithFallback) PendingBalanceAt(ctx context.Context, account commo
|
|
|
|
|
rpcstats.CountCall("eth_PendingBalanceAt")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.PendingBalanceAt(ctx, account)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -507,7 +507,7 @@ func (c *ClientWithFallback) PendingStorageAt(ctx context.Context, account commo
|
|
|
|
|
rpcstats.CountCall("eth_PendingStorageAt")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.PendingStorageAt(ctx, account, key)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -525,7 +525,7 @@ func (c *ClientWithFallback) PendingCodeAt(ctx context.Context, account common.A
|
|
|
|
|
rpcstats.CountCall("eth_PendingCodeAt")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.PendingCodeAt(ctx, account)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -543,7 +543,7 @@ func (c *ClientWithFallback) PendingNonceAt(ctx context.Context, account common.
|
|
|
|
|
rpcstats.CountCall("eth_PendingNonceAt")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.PendingNonceAt(ctx, account)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -561,7 +561,7 @@ func (c *ClientWithFallback) PendingTransactionCount(ctx context.Context) (uint,
|
|
|
|
|
rpcstats.CountCall("eth_PendingTransactionCount")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.PendingTransactionCount(ctx)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -579,7 +579,7 @@ func (c *ClientWithFallback) CallContract(ctx context.Context, msg ethereum.Call
|
|
|
|
|
rpcstats.CountCall("eth_CallContract_" + msg.To.String())
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.CallContract(ctx, msg, blockNumber)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -597,7 +597,7 @@ func (c *ClientWithFallback) PendingCallContract(ctx context.Context, msg ethere
|
|
|
|
|
rpcstats.CountCall("eth_PendingCallContract")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.PendingCallContract(ctx, msg)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -615,7 +615,7 @@ func (c *ClientWithFallback) SuggestGasPrice(ctx context.Context) (*big.Int, err
|
|
|
|
|
rpcstats.CountCall("eth_SuggestGasPrice")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.SuggestGasPrice(ctx)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -633,7 +633,7 @@ func (c *ClientWithFallback) SuggestGasTipCap(ctx context.Context) (*big.Int, er
|
|
|
|
|
rpcstats.CountCall("eth_SuggestGasTipCap")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.SuggestGasTipCap(ctx)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -651,7 +651,7 @@ func (c *ClientWithFallback) FeeHistory(ctx context.Context, blockCount uint64,
|
|
|
|
|
rpcstats.CountCall("eth_FeeHistory")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.FeeHistory(ctx, blockCount, lastBlock, rewardPercentiles)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -669,7 +669,7 @@ func (c *ClientWithFallback) EstimateGas(ctx context.Context, msg ethereum.CallM
|
|
|
|
|
rpcstats.CountCall("eth_EstimateGas")
|
|
|
|
|
|
|
|
|
|
res, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return client.EstimateGas(ctx, msg)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -687,7 +687,7 @@ func (c *ClientWithFallback) SendTransaction(ctx context.Context, tx *types.Tran
|
|
|
|
|
rpcstats.CountCall("eth_SendTransaction")
|
|
|
|
|
|
|
|
|
|
_, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return nil, client.SendTransaction(ctx, tx)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -701,7 +701,7 @@ func (c *ClientWithFallback) CallContext(ctx context.Context, result interface{}
|
|
|
|
|
rpcstats.CountCall("eth_CallContext")
|
|
|
|
|
|
|
|
|
|
_, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return nil, client.CallContext(ctx, result, method, args...)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
@ -715,7 +715,7 @@ func (c *ClientWithFallback) BatchCallContext(ctx context.Context, b []rpc.Batch
|
|
|
|
|
rpcstats.CountCall("eth_BatchCallContext")
|
|
|
|
|
|
|
|
|
|
_, err := c.makeCall(
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.RPSLimitedEthClientInterface) (interface{}, error) {
|
|
|
|
|
ctx, c.ethClients, func(client ethclient.EthClientInterface) (interface{}, error) {
|
|
|
|
|
return nil, client.BatchCallContext(ctx, b)
|
|
|
|
|
},
|
|
|
|
|
)
|
|
|
|
|