client

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 3, 2022 License: MIT Imports: 26 Imported by: 2

Documentation

Index

Constants

View Source
const (
	NonceTooLow = iota
	ReplacementTransactionUnderpriced
	LimitReached
	TransactionAlreadyInMempool
	TerminallyUnderpriced
	InsufficientEth
	TooExpensive
	FeeTooLow
	FeeTooHigh
	Fatal
)
View Source
const (
	NodeStateUndialed = NodeState(iota)
	NodeStateDialed
	NodeStateInvalidChainID
	NodeStateAlive
	NodeStateDead
	NodeStateClosed
)
View Source
const NullClientChainID = 0

NullClientChainID the ChainID that nullclient will return 0 is never used as a real chain ID so makes sense as a dummy value here

Variables

This section is empty.

Functions

func DefaultQueryCtx

func DefaultQueryCtx(ctxs ...context.Context) (ctx context.Context, cancel context.CancelFunc)

DefaultQueryCtx returns a context with a sensible sanity limit timeout for queries to the eth node This is a sanity limit to try to work around poorly behaved remote WS endpoints that fail to send us data that we requested NO QUERY should ever take longer than this

func ExtractRevertReasonFromRPCError

func ExtractRevertReasonFromRPCError(err error) (string, error)

ExtractRevertReasonFromRPCError attempts to extract the revert reason from the response of an RPC eth_call that reverted by parsing the message from the "data" field ex: kovan (parity) { "error": { "code" : -32015, "data": "Reverted 0xABC123...", "message": "VM execution error." } } // revert reason always omitted rinkeby / ropsten (geth) { "error": { "code": 3, "data": "0x0xABC123...", "message": "execution reverted: hello world" } } // revert reason included in message

func NewClientWithNodes

func NewClientWithNodes(logger logger.Logger, primaryNodes []Node, sendOnlyNodes []SendOnlyNode, chainID *big.Int) (*client, error)

NewClientWithNodes instantiates a client from a list of nodes Currently only supports one primary

func ToBlockNumArg

func ToBlockNumArg(number *big.Int) string

Types

type CallArgs

type CallArgs struct {
	To   common.Address `json:"to"`
	Data hexutil.Bytes  `json:"data"`
}

CallArgs represents the data used to call the balance method of a contract. "To" is the address of the ERC contract. "Data" is the message sent to the contract.

type Client

type Client interface {
	Dial(ctx context.Context) error
	Close()
	ChainID() *big.Int

	GetERC20Balance(address common.Address, contractAddress common.Address) (*big.Int, error)
	GetLINKBalance(linkAddress common.Address, address common.Address) (*assets.Link, error)
	GetEthBalance(ctx context.Context, account common.Address, blockNumber *big.Int) (*assets.Eth, error)

	// Wrapped RPC methods
	Call(result interface{}, method string, args ...interface{}) error
	CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
	BatchCallContext(ctx context.Context, b []rpc.BatchElem) error

	// HeadByNumber is a reimplemented version of HeaderByNumber due to a
	// difference in how block header hashes are calculated by Parity nodes
	// running on Kovan.  We have to return our own wrapper type to capture the
	// correct hash from the RPC response.
	HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error)
	SubscribeNewHead(ctx context.Context, ch chan<- *evmtypes.Head) (ethereum.Subscription, error)

	// Wrapped Geth client methods
	SendTransaction(ctx context.Context, tx *types.Transaction) error
	PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
	PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
	NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
	TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
	BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
	BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
	FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
	SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error)
	EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)
	SuggestGasPrice(ctx context.Context) (*big.Int, error)
	CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
	CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)

	// bind.ContractBackend methods
	HeaderByNumber(context.Context, *big.Int) (*types.Header, error)
	SuggestGasTipCap(ctx context.Context) (*big.Int, error)
}

Client is the interface used to interact with an ethereum node.

type ClientErrors

type ClientErrors = map[int]*regexp.Regexp

type JsonError

type JsonError struct {
	Code    int         `json:"code"`
	Message string      `json:"message"`
	Data    interface{} `json:"data,omitempty"`
}

go-ethereum@v1.10.0/rpc/json.go

func ExtractRPCError

func ExtractRPCError(err error) *JsonError

func (*JsonError) Error

func (err *JsonError) Error() string

func (*JsonError) String

func (err *JsonError) String() string

type Node

type Node interface {
	Dial(ctx context.Context) error
	Close()
	Verify(ctx context.Context, expectedChainID *big.Int) (err error)

	State() NodeState

	CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
	BatchCallContext(ctx context.Context, b []rpc.BatchElem) error
	SendTransaction(ctx context.Context, tx *types.Transaction) error
	PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
	PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
	NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
	TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
	BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
	BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
	FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
	SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error)
	EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)
	SuggestGasPrice(ctx context.Context) (*big.Int, error)
	CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
	CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)
	HeaderByNumber(context.Context, *big.Int) (*types.Header, error)
	SuggestGasTipCap(ctx context.Context) (*big.Int, error)
	EthSubscribe(ctx context.Context, channel interface{}, args ...interface{}) (ethereum.Subscription, error)
	ChainID(ctx context.Context) (chainID *big.Int, err error)

	String() string
}

func NewNode

func NewNode(lggr logger.Logger, wsuri url.URL, httpuri *url.URL, name string) Node

type NodeState

type NodeState int

type NullClient

type NullClient struct {
	// contains filtered or unexported fields
}

NullClient satisfies the Client but has no side effects

func NewNullClient

func NewNullClient(cid *big.Int, lggr logger.Logger) *NullClient

func (*NullClient) BalanceAt

func (nc *NullClient) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)

func (*NullClient) BatchCallContext

func (nc *NullClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error

func (*NullClient) BlockByNumber

func (nc *NullClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)

func (*NullClient) Call

func (nc *NullClient) Call(result interface{}, method string, args ...interface{}) error

func (*NullClient) CallContext

func (nc *NullClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error

func (*NullClient) CallContract

func (nc *NullClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)

func (*NullClient) ChainID

func (nc *NullClient) ChainID() *big.Int

func (*NullClient) Close

func (nc *NullClient) Close()

func (*NullClient) CodeAt

func (nc *NullClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)

func (*NullClient) Dial

func (nc *NullClient) Dial(context.Context) error

func (*NullClient) EstimateGas

func (nc *NullClient) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)

func (*NullClient) FilterLogs

func (nc *NullClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)

func (*NullClient) GetERC20Balance

func (nc *NullClient) GetERC20Balance(address common.Address, contractAddress common.Address) (*big.Int, error)

func (*NullClient) GetEthBalance

func (nc *NullClient) GetEthBalance(context.Context, common.Address, *big.Int) (*assets.Eth, error)

func (*NullClient) GetLINKBalance

func (nc *NullClient) GetLINKBalance(linkAddress common.Address, address common.Address) (*assets.Link, error)

func (*NullClient) HeadByNumber

func (nc *NullClient) HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error)

func (*NullClient) HeaderByNumber

func (nc *NullClient) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error)

func (*NullClient) NonceAt

func (nc *NullClient) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)

func (*NullClient) PendingCodeAt

func (nc *NullClient) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)

func (*NullClient) PendingNonceAt

func (nc *NullClient) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)

func (*NullClient) SendTransaction

func (nc *NullClient) SendTransaction(ctx context.Context, tx *types.Transaction) error

func (*NullClient) SubscribeFilterLogs

func (nc *NullClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error)

func (*NullClient) SubscribeNewHead

func (nc *NullClient) SubscribeNewHead(ctx context.Context, ch chan<- *evmtypes.Head) (ethereum.Subscription, error)

func (*NullClient) SuggestGasPrice

func (nc *NullClient) SuggestGasPrice(ctx context.Context) (*big.Int, error)

func (*NullClient) SuggestGasTipCap

func (nc *NullClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err error)

func (*NullClient) TransactionReceipt

func (nc *NullClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)

type Pool

type Pool struct {
	utils.StartStopOnce
	// contains filtered or unexported fields
}

Pool represents an abstraction over one or more primary nodes It is responsible for liveness checking and balancing queries across live nodes

func NewPool

func NewPool(logger logger.Logger, nodes []Node, sendonlys []SendOnlyNode, chainID *big.Int) *Pool

func (*Pool) BalanceAt

func (p *Pool) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)

func (*Pool) BatchCallContext

func (p *Pool) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error

func (*Pool) BlockByNumber

func (p *Pool) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)

func (*Pool) CallContext

func (p *Pool) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error

func (*Pool) CallContract

func (p *Pool) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)

func (*Pool) ChainID

func (p *Pool) ChainID() *big.Int

func (*Pool) Close

func (p *Pool) Close()

func (*Pool) CodeAt

func (p *Pool) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)

func (*Pool) Dial

func (p *Pool) Dial(ctx context.Context) error

Dial dials every node in the pool and verifies their chain IDs are consistent.

func (*Pool) EstimateGas

func (p *Pool) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)

func (*Pool) EthSubscribe

func (p *Pool) EthSubscribe(ctx context.Context, channel interface{}, args ...interface{}) (ethereum.Subscription, error)

func (*Pool) FilterLogs

func (p *Pool) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)

func (*Pool) HeaderByNumber

func (p *Pool) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error)

bind.ContractBackend methods

func (*Pool) NonceAt

func (p *Pool) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)

func (*Pool) PendingCodeAt

func (p *Pool) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)

func (*Pool) PendingNonceAt

func (p *Pool) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)

func (*Pool) SendTransaction

func (p *Pool) SendTransaction(ctx context.Context, tx *types.Transaction) error

Wrapped Geth client methods

func (*Pool) SubscribeFilterLogs

func (p *Pool) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error)

func (*Pool) SuggestGasPrice

func (p *Pool) SuggestGasPrice(ctx context.Context) (*big.Int, error)

func (*Pool) SuggestGasTipCap

func (p *Pool) SuggestGasTipCap(ctx context.Context) (*big.Int, error)

func (*Pool) TransactionReceipt

func (p *Pool) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)

type SendError

type SendError struct {
	// contains filtered or unexported fields
}

fatal means this transaction can never be accepted even with a different nonce or higher gas price

func NewFatalSendError

func NewFatalSendError(e error) *SendError

func NewSendError

func NewSendError(e error) *SendError

func NewSendErrorS

func NewSendErrorS(s string) *SendError

func (*SendError) CauseStr

func (s *SendError) CauseStr() string

CauseStr returns the string of the original error

func (*SendError) Error

func (s *SendError) Error() string

func (*SendError) Fatal

func (s *SendError) Fatal() bool

Fatal indicates whether the error should be considered fatal or not Fatal errors mean that no matter how many times the send is retried, no node will ever accept it

func (*SendError) IsFeeTooHigh

func (s *SendError) IsFeeTooHigh() bool

IsFeeTooHigh is an optimism-specific error returned when total fee is too high

func (*SendError) IsFeeTooLow

func (s *SendError) IsFeeTooLow() bool

IsFeeTooLow is an optimism-specific error returned when total fee is too low

func (*SendError) IsInsufficientEth

func (s *SendError) IsInsufficientEth() bool

func (*SendError) IsNonceTooLowError

func (s *SendError) IsNonceTooLowError() bool

func (*SendError) IsReplacementUnderpriced

func (s *SendError) IsReplacementUnderpriced() bool

IsReplacementUnderpriced indicates that a transaction already exists in the mempool with this nonce but a different gas price or payload

func (*SendError) IsTemporarilyUnderpriced

func (s *SendError) IsTemporarilyUnderpriced() bool

func (*SendError) IsTerminallyUnderpriced

func (s *SendError) IsTerminallyUnderpriced() bool

IsTerminallyUnderpriced indicates that this transaction is so far underpriced the node won't even accept it in the first place

func (*SendError) IsTooExpensive

func (s *SendError) IsTooExpensive() bool

IsTooExpensive returns true if the transaction and gas price are combined in some way that makes the total transaction too expensive for the eth node to accept at all. No amount of retrying at this or higher gas prices can ever succeed.

func (*SendError) IsTransactionAlreadyInMempool

func (s *SendError) IsTransactionAlreadyInMempool() bool

Geth/parity returns this error if the transaction is already in the node's mempool

type SendOnlyNode

type SendOnlyNode interface {
	Dial(context.Context) error
	Verify(ctx context.Context, expectedChainID *big.Int) (err error)
	ChainID(ctx context.Context) (chainID *big.Int, err error)

	SendTransaction(ctx context.Context, tx *types.Transaction) error
	BatchCallContext(ctx context.Context, b []rpc.BatchElem) error

	String() string
}

SendOnlyNode represents one ethereum node used as a sendonly

func NewSendOnlyNode

func NewSendOnlyNode(lggr logger.Logger, httpuri url.URL, name string) SendOnlyNode

type SimulatedBackendClient

type SimulatedBackendClient struct {
	// contains filtered or unexported fields
}

SimulatedBackendClient is an Client implementation using a simulated blockchain backend. Note that not all RPC methods are implemented here.

func NewSimulatedBackendClient

func NewSimulatedBackendClient(t testing.TB, b *backends.SimulatedBackend, chainId *big.Int) *SimulatedBackendClient

NewSimulatedBackendClient creates an eth client backed by a simulated backend.

func (*SimulatedBackendClient) BalanceAt

func (c *SimulatedBackendClient) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)

BalanceAt gets balance as of a specified block.

func (*SimulatedBackendClient) BatchCallContext

func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error

BatchCallContext makes a batch rpc call.

func (*SimulatedBackendClient) BlockByNumber

func (c *SimulatedBackendClient) BlockByNumber(ctx context.Context, n *big.Int) (*types.Block, error)

BlockByNumber returns a geth block type.

func (*SimulatedBackendClient) Call

func (c *SimulatedBackendClient) Call(result interface{}, method string, args ...interface{}) error

Call makes a call.

func (*SimulatedBackendClient) CallContext

func (c *SimulatedBackendClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error

CallContext mocks the ethereum client RPC calls used by chainlink, copying the return value into result.

func (*SimulatedBackendClient) CallContract

func (c *SimulatedBackendClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)

CallContract calls a contract.

func (*SimulatedBackendClient) ChainID

func (c *SimulatedBackendClient) ChainID() *big.Int

ChainID returns the ethereum ChainID.

func (*SimulatedBackendClient) Close

func (c *SimulatedBackendClient) Close()

Close does nothing. We ought not close the underlying backend here since other simulated clients might still be using it

func (*SimulatedBackendClient) CodeAt

func (c *SimulatedBackendClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)

CodeAt gets the code associated with an account as of a specified block.

func (*SimulatedBackendClient) Dial

Dial noop for the sim.

func (*SimulatedBackendClient) EstimateGas

func (c *SimulatedBackendClient) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error)

EstimateGas estimates gas for a msg.

func (*SimulatedBackendClient) FilterLogs

func (c *SimulatedBackendClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) (logs []types.Log, err error)

FilterLogs returns all logs that respect the passed filter query.

func (*SimulatedBackendClient) GetERC20Balance

func (c *SimulatedBackendClient) GetERC20Balance(address common.Address, contractAddress common.Address) (balance *big.Int, err error)

GetERC20Balance returns the balance of the given address for the token contract address.

func (*SimulatedBackendClient) GetEthBalance

func (c *SimulatedBackendClient) GetEthBalance(ctx context.Context, account common.Address, blockNumber *big.Int) (*assets.Eth, error)

GetEthBalance helper to get eth balance

func (*SimulatedBackendClient) GetLINKBalance

func (c *SimulatedBackendClient) GetLINKBalance(linkAddress common.Address, address common.Address) (*assets.Link, error)

GetLINKBalance get link balance.

func (*SimulatedBackendClient) HeadByNumber

func (c *SimulatedBackendClient) HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error)

HeadByNumber returns our own header type.

func (*SimulatedBackendClient) HeaderByNumber

func (c *SimulatedBackendClient) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error)

HeaderByNumber returns the geth header type.

func (*SimulatedBackendClient) NonceAt

func (c *SimulatedBackendClient) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)

NonceAt gets nonce as of a specified block.

func (*SimulatedBackendClient) PendingCodeAt

func (c *SimulatedBackendClient) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)

PendingCodeAt gets the latest code.

func (*SimulatedBackendClient) PendingNonceAt

func (c *SimulatedBackendClient) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)

PendingNonceAt gets pending nonce i.e. mempool nonce.

func (*SimulatedBackendClient) SendTransaction

func (c *SimulatedBackendClient) SendTransaction(ctx context.Context, tx *types.Transaction) error

SendTransaction sends a transaction.

func (*SimulatedBackendClient) SubscribeFilterLogs

func (c *SimulatedBackendClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, channel chan<- types.Log) (ethereum.Subscription, error)

SubscribeFilterLogs registers a subscription for push notifications of logs from a given address.

func (*SimulatedBackendClient) SubscribeNewHead

func (c *SimulatedBackendClient) SubscribeNewHead(
	ctx context.Context,
	channel chan<- *evmtypes.Head,
) (ethereum.Subscription, error)

SubscribeNewHead registers a subscription for push notifications of new blocks. Note the sim's API only accepts types.Head so we have this goroutine to convert those into evmtypes.Head.

func (*SimulatedBackendClient) SuggestGasPrice

func (c *SimulatedBackendClient) SuggestGasPrice(ctx context.Context) (*big.Int, error)

SuggestGasPrice recommends a gas price.

func (*SimulatedBackendClient) SuggestGasTipCap

func (c *SimulatedBackendClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err error)

SuggestGasTipCap suggests a gas tip cap.

func (*SimulatedBackendClient) TransactionReceipt

func (c *SimulatedBackendClient) TransactionReceipt(ctx context.Context, receipt common.Hash) (*types.Receipt, error)

TransactionReceipt returns the transaction receipt for the given transaction hash.

type Subscription

type Subscription interface {
	Err() <-chan error
	Unsubscribe()
}

This interface only exists so that we can generate a mock for it. It is identical to `ethereum.Subscription`.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL