blockbook/bchain/coins/avalanche/evm.go
Sai Raj 49ca2ba2cf Self restart on repeated error and package name
- Adding self restart when repeated error occurs with backend rpc connection

- renamed package name to reflect correctly
2024-07-01 22:20:48 -04:00

144 lines
4.8 KiB
Go

package avalanche
import (
"context"
"math/big"
"strings"
"github.com/ava-labs/coreth/core/types"
"github.com/ava-labs/coreth/ethclient"
"github.com/ava-labs/coreth/interfaces"
"github.com/ava-labs/coreth/rpc"
"github.com/ethereum/go-ethereum/common"
"github.com/ranchimall/blockbook/bchain"
)
// AvalancheClient wraps a client to implement the EVMClient interface
type AvalancheClient struct {
ethclient.Client
}
// HeaderByNumber returns a block header that implements the EVMHeader interface
func (c *AvalancheClient) HeaderByNumber(ctx context.Context, number *big.Int) (bchain.EVMHeader, error) {
h, err := c.Client.HeaderByNumber(ctx, number)
if err != nil {
return nil, err
}
return &AvalancheHeader{Header: h}, nil
}
// EstimateGas returns the current estimated gas cost for executing a transaction
func (c *AvalancheClient) EstimateGas(ctx context.Context, msg interface{}) (uint64, error) {
return c.Client.EstimateGas(ctx, msg.(interfaces.CallMsg))
}
// BalanceAt returns the balance for the given account at a specific block, or latest known block if no block number is provided
func (c *AvalancheClient) BalanceAt(ctx context.Context, addrDesc bchain.AddressDescriptor, blockNumber *big.Int) (*big.Int, error) {
return c.Client.BalanceAt(ctx, common.BytesToAddress(addrDesc), blockNumber)
}
// NonceAt returns the nonce for the given account at a specific block, or latest known block if no block number is provided
func (c *AvalancheClient) NonceAt(ctx context.Context, addrDesc bchain.AddressDescriptor, blockNumber *big.Int) (uint64, error) {
return c.Client.NonceAt(ctx, common.BytesToAddress(addrDesc), blockNumber)
}
// AvalancheRPCClient wraps an rpc client to implement the EVMRPCClient interface
type AvalancheRPCClient struct {
*rpc.Client
}
// EthSubscribe subscribes to events and returns a client subscription that implements the EVMClientSubscription interface
func (c *AvalancheRPCClient) EthSubscribe(ctx context.Context, channel interface{}, args ...interface{}) (bchain.EVMClientSubscription, error) {
sub, err := c.Client.EthSubscribe(ctx, channel, args...)
if err != nil {
return nil, err
}
return &AvalancheClientSubscription{ClientSubscription: sub}, nil
}
// CallContext performs a JSON-RPC call with the given arguments
func (c *AvalancheRPCClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error {
err := c.Client.CallContext(ctx, result, method, args...)
// unfinalized data cannot be queried error returned when trying to query a block height greater than last finalized block
// do not throw rpc error and instead treat as ErrBlockNotFound
// https://docs.avax.network/quickstart/exchanges/integrate-exchange-with-avalanche#determining-finality
if err != nil && !strings.Contains(err.Error(), "cannot query unfinalized data") {
return err
}
return nil
}
// AvalancheHeader wraps a block header to implement the EVMHeader interface
type AvalancheHeader struct {
*types.Header
}
// Hash returns the block hash as a hex string
func (h *AvalancheHeader) Hash() string {
return h.Header.Hash().Hex()
}
// Number returns the block number
func (h *AvalancheHeader) Number() *big.Int {
return h.Header.Number
}
// Difficulty returns the block difficulty
func (h *AvalancheHeader) Difficulty() *big.Int {
return h.Header.Difficulty
}
// AvalancheHash wraps a transaction hash to implement the EVMHash interface
type AvalancheHash struct {
common.Hash
}
// AvalancheClientSubscription wraps a client subcription to implement the EVMClientSubscription interface
type AvalancheClientSubscription struct {
*rpc.ClientSubscription
}
// AvalancheNewBlock wraps a block header channel to implement the EVMNewBlockSubscriber interface
type AvalancheNewBlock struct {
channel chan *types.Header
}
// Channel returns the underlying channel as an empty interface
func (s *AvalancheNewBlock) Channel() interface{} {
return s.channel
}
// Read from the underlying channel and return a block header that implements the EVMHeader interface
func (s *AvalancheNewBlock) Read() (bchain.EVMHeader, bool) {
h, ok := <-s.channel
return &AvalancheHeader{Header: h}, ok
}
// Close the underlying channel
func (s *AvalancheNewBlock) Close() {
close(s.channel)
}
// AvalancheNewTx wraps a transaction hash channel to conform with the EVMNewTxSubscriber interface
type AvalancheNewTx struct {
channel chan common.Hash
}
// Channel returns the underlying channel as an empty interface
func (s *AvalancheNewTx) Channel() interface{} {
return s.channel
}
// Read from the underlying channel and return a transaction hash that implements the EVMHash interface
func (s *AvalancheNewTx) Read() (bchain.EVMHash, bool) {
h, ok := <-s.channel
return &AvalancheHash{Hash: h}, ok
}
// Close the underlying channel
func (s *AvalancheNewTx) Close() {
close(s.channel)
}