Documentation
¶
Overview ¶
The simulated backend cannot access old blocks and will return an error if anything other than `latest`, `nil`, or the latest block are passed to `CallContract`.
The simulated client avoids the old block error from the simulated backend by passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext` and will not return an error when an old block is used.
Index ¶
- Constants
- func ClassifySendError(err error, clientErrors config.ClientErrors, lggr logger.SugaredLogger, ...) multinode.SendTxReturnCode
- func FinalizeLatest(t *testing.T, backend evmtypes.Backend)
- func FinalizeThroughBlock(t *testing.T, backend evmtypes.Backend, client HeadReader, blockNumber int64)
- func IsTooManyResults(err error, clientErrors config.ClientErrors) bool
- func NewClientConfigs(selectionMode *string, leaseDuration time.Duration, chainType string, ...) (multinode.ChainConfig, evmconfig.NodePool, []*toml.Node, error)
- func NewTxError(e error) commontypes.ErrorClassifier
- func ToBackwardCompatibleBlockNumArg(number *big.Int) string
- func ToBackwardCompatibleCallArg(msg ethereum.CallMsg) interface{}
- func ToBlockNumArg(number *big.Int) string
- type CallArgs
- type Client
- type ClientErrors
- type HeadReader
- type JsonError
- type NodeConfig
- type NullClient
- func (nc *NullClient) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
- func (nc *NullClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error
- func (nc *NullClient) BatchCallContextAll(ctx context.Context, b []rpc.BatchElem) error
- func (nc *NullClient) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
- func (nc *NullClient) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
- func (nc *NullClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
- func (nc *NullClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
- func (nc *NullClient) ChainID() (*big.Int, error)
- func (nc *NullClient) CheckTxValidity(_ context.Context, _ common.Address, _ common.Address, _ []byte) *SendError
- func (nc *NullClient) Close()
- func (nc *NullClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)
- func (nc *NullClient) ConfiguredChainID() *big.Int
- func (nc *NullClient) Dial(context.Context) error
- func (nc *NullClient) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)
- func (nc *NullClient) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, ...) (feeHistory *ethereum.FeeHistory, err error)
- func (nc *NullClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
- func (nc *NullClient) HeadByHash(ctx context.Context, h common.Hash) (*evmtypes.Head, error)
- func (nc *NullClient) HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error)
- func (nc *NullClient) HeaderByHash(ctx context.Context, h common.Hash) (*types.Header, error)
- func (nc *NullClient) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error)
- func (nc *NullClient) IsL2() bool
- func (nc *NullClient) LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*assets.Link, error)
- func (nc *NullClient) LatestBlockHeight(ctx context.Context) (*big.Int, error)
- func (nc *NullClient) LatestFinalizedBlock(_ context.Context) (*evmtypes.Head, error)
- func (nc *NullClient) NodeStates() map[string]string
- func (nc *NullClient) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
- func (nc *NullClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error)
- func (nc *NullClient) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
- func (nc *NullClient) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
- func (nc *NullClient) SendTransaction(ctx context.Context, tx *types.Transaction) error
- func (nc *NullClient) SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, sender common.Address) (multinode.SendTxReturnCode, error)
- func (nc *NullClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (ethereum.Subscription, error)
- func (nc *NullClient) SubscribeToHeads(ctx context.Context) (<-chan *evmtypes.Head, ethereum.Subscription, error)
- func (nc *NullClient) SuggestGasPrice(ctx context.Context) (*big.Int, error)
- func (nc *NullClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err error)
- func (nc *NullClient) TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (*big.Int, error)
- func (nc *NullClient) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, error)
- func (nc *NullClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
- type RPCClient
- func (r *RPCClient) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (balance *big.Int, err error)
- func (r *RPCClient) BatchCallContext(rootCtx context.Context, b []rpc.BatchElem) error
- func (r *RPCClient) BlockByHash(ctx context.Context, hash common.Hash) (head *evmtypes.Head, err error)
- func (r *RPCClient) BlockByHashGeth(ctx context.Context, hash common.Hash) (block *types.Block, err error)
- func (r *RPCClient) BlockByNumber(ctx context.Context, number *big.Int) (head *evmtypes.Head, err error)
- func (r *RPCClient) BlockByNumberGeth(ctx context.Context, number *big.Int) (block *types.Block, err error)
- func (r *RPCClient) BlockNumber(ctx context.Context) (height uint64, err error)
- func (r *RPCClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
- func (r *RPCClient) CallContract(ctx context.Context, msg interface{}, blockNumber *big.Int) (val []byte, err error)
- func (r *RPCClient) ChainID(ctx context.Context) (chainID *big.Int, err error)
- func (r *RPCClient) ClientVersion(ctx context.Context) (version string, err error)
- func (r *RPCClient) Close()
- func (r *RPCClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) (code []byte, err error)
- func (r *RPCClient) Dial(callerCtx context.Context) error
- func (r *RPCClient) DialHTTP() error
- func (r *RPCClient) EstimateGas(ctx context.Context, c interface{}) (gas uint64, err error)
- func (r *RPCClient) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, ...) (feeHistory *ethereum.FeeHistory, err error)
- func (r *RPCClient) FilterEvents(ctx context.Context, q ethereum.FilterQuery) ([]types.Log, error)
- func (r *RPCClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) (l []types.Log, err error)
- func (r *RPCClient) HeaderByHash(ctx context.Context, hash common.Hash) (header *types.Header, err error)
- func (r *RPCClient) HeaderByNumber(ctx context.Context, number *big.Int) (header *types.Header, err error)
- func (r *RPCClient) IsSyncing(ctx context.Context) (bool, error)
- func (r *RPCClient) LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*commonassets.Link, error)
- func (r *RPCClient) LatestBlockHeight(ctx context.Context) (*big.Int, error)
- func (r *RPCClient) Name() string
- func (r *RPCClient) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (nonce uint64, err error)
- func (r *RPCClient) PendingCallContract(ctx context.Context, msg interface{}) (val []byte, err error)
- func (r *RPCClient) PendingCodeAt(ctx context.Context, account common.Address) (code []byte, err error)
- func (r *RPCClient) PendingSequenceAt(ctx context.Context, account common.Address) (nonce evmtypes.Nonce, err error)
- func (r *RPCClient) Ping(ctx context.Context) error
- func (r *RPCClient) SendEmptyTransaction(ctx context.Context, ...) (txhash string, err error)
- func (r *RPCClient) SendTransaction(ctx context.Context, tx *types.Transaction) (struct{}, multinode.SendTxReturnCode, error)
- func (r *RPCClient) SimulateTransaction(ctx context.Context, tx *types.Transaction) error
- func (r *RPCClient) String() string
- func (r *RPCClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, ch chan<- types.Log) (_ ethereum.Subscription, err error)
- func (r *RPCClient) SubscribeToHeads(ctx context.Context) (ch <-chan *evmtypes.Head, sub multinode.Subscription, err error)
- func (r *RPCClient) SuggestGasPrice(ctx context.Context) (price *big.Int, err error)
- func (r *RPCClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err error)
- func (r *RPCClient) TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (*big.Int, error)
- func (r *RPCClient) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, err error)
- func (r *RPCClient) TransactionReceipt(ctx context.Context, txHash common.Hash) (receipt *evmtypes.Receipt, err error)
- func (r *RPCClient) TransactionReceiptGeth(ctx context.Context, txHash common.Hash) (receipt *types.Receipt, err error)
- type SendError
- func (s *SendError) Error() string
- func (s *SendError) Fatal(configErrors *ClientErrors) bool
- func (s *SendError) IsCanceled() bool
- func (s *SendError) IsFatal() bool
- func (s *SendError) IsInsufficientEth(configErrors *ClientErrors) bool
- func (s *SendError) IsL2FeeTooHigh(configErrors *ClientErrors) bool
- func (s *SendError) IsL2Full(configErrors *ClientErrors) bool
- func (s *SendError) IsNonceTooHighError(configErrors *ClientErrors) bool
- func (s *SendError) IsNonceTooLowError(configErrors *ClientErrors) bool
- func (s *SendError) IsReplacementUnderpriced(configErrors *ClientErrors) bool
- func (s *SendError) IsServiceTimeout(configErrors *ClientErrors) bool
- func (s *SendError) IsServiceUnavailable(configErrors *ClientErrors) bool
- func (s *SendError) IsTemporarilyUnderpriced(configErrors *ClientErrors) bool
- func (s *SendError) IsTerminallyStuckConfigError(configErrors *ClientErrors) bool
- func (s *SendError) IsTerminallyUnderpriced(configErrors *ClientErrors) bool
- func (s *SendError) IsTimeout() bool
- func (s *SendError) IsTransactionAlreadyInMempool(configErrors *ClientErrors) bool
- func (s *SendError) IsTransactionAlreadyMined(configErrors *ClientErrors) bool
- func (s *SendError) IsTxFeeExceedsCap(configErrors *ClientErrors) bool
- func (s *SendError) L2FeeTooLow(configErrors *ClientErrors) bool
- type SimulatedBackendClient
- func (c *SimulatedBackendClient) Backend() evmtypes.Backend
- func (c *SimulatedBackendClient) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error)
- func (c *SimulatedBackendClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error
- func (c *SimulatedBackendClient) BatchCallContextAll(ctx context.Context, b []rpc.BatchElem) error
- func (c *SimulatedBackendClient) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
- func (c *SimulatedBackendClient) BlockByNumber(ctx context.Context, n *big.Int) (*types.Block, error)
- func (c *SimulatedBackendClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
- func (c *SimulatedBackendClient) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error)
- func (c *SimulatedBackendClient) ChainID() (*big.Int, error)
- func (c *SimulatedBackendClient) CheckTxValidity(ctx context.Context, from common.Address, to common.Address, data []byte) *SendError
- func (c *SimulatedBackendClient) Close()
- func (c *SimulatedBackendClient) CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, error)
- func (c *SimulatedBackendClient) Commit() common.Hash
- func (c *SimulatedBackendClient) ConfiguredChainID() *big.Int
- func (c *SimulatedBackendClient) Dial(context.Context) error
- func (c *SimulatedBackendClient) EstimateGas(ctx context.Context, call ethereum.CallMsg) (gas uint64, err error)
- func (c *SimulatedBackendClient) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, ...) (feeHistory *ethereum.FeeHistory, err error)
- func (c *SimulatedBackendClient) FilterLogs(ctx context.Context, q ethereum.FilterQuery) (logs []types.Log, err error)
- func (c *SimulatedBackendClient) HeadByHash(ctx context.Context, h common.Hash) (*evmtypes.Head, error)
- func (c *SimulatedBackendClient) HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error)
- func (c *SimulatedBackendClient) HeaderByHash(ctx context.Context, h common.Hash) (*types.Header, error)
- func (c *SimulatedBackendClient) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error)
- func (c *SimulatedBackendClient) IsL2() bool
- func (c *SimulatedBackendClient) LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*assets.Link, error)
- func (c *SimulatedBackendClient) LatestBlockHeight(ctx context.Context) (*big.Int, error)
- func (c *SimulatedBackendClient) LatestFinalizedBlock(ctx context.Context) (*evmtypes.Head, error)
- func (c *SimulatedBackendClient) NodeStates() map[string]string
- func (c *SimulatedBackendClient) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (uint64, error)
- func (c *SimulatedBackendClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error)
- func (c *SimulatedBackendClient) PendingCodeAt(ctx context.Context, account common.Address) ([]byte, error)
- func (c *SimulatedBackendClient) PendingNonceAt(ctx context.Context, account common.Address) (uint64, error)
- func (c *SimulatedBackendClient) RegisterHeadByNumberCallback(cb func(ctx context.Context, c *SimulatedBackendClient, n *big.Int) error)
- func (c *SimulatedBackendClient) SendTransaction(ctx context.Context, tx *types.Transaction) error
- func (c *SimulatedBackendClient) SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, fromAddress common.Address) (multinode.SendTxReturnCode, error)
- func (c *SimulatedBackendClient) SetBackend(backend evmtypes.Backend, chainType chaintype.ChainType)
- func (c *SimulatedBackendClient) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuery, channel chan<- types.Log) (ethereum.Subscription, error)
- func (c *SimulatedBackendClient) SubscribeToHeads(ctx context.Context) (<-chan *evmtypes.Head, ethereum.Subscription, error)
- func (c *SimulatedBackendClient) SuggestGasPrice(ctx context.Context) (*big.Int, error)
- func (c *SimulatedBackendClient) SuggestGasTipCap(ctx context.Context) (tipCap *big.Int, err error)
- func (c *SimulatedBackendClient) TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (balance *big.Int, err error)
- func (c *SimulatedBackendClient) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, err error)
- func (c *SimulatedBackendClient) TransactionReceipt(ctx context.Context, receipt common.Hash) (*types.Receipt, error)
Constants ¶
const ( NonceTooLow = iota // Nethermind specific error. Nethermind throws a NonceGap error when the tx nonce is greater than current_nonce + tx_count_in_mempool, instead of keeping the tx in mempool. // See: https://github.com/NethermindEth/nethermind/blob/master/src/Nethermind/Nethermind.TxPool/Filters/GapNonceFilter.cs NonceTooHigh ReplacementTransactionUnderpriced LimitReached TransactionAlreadyInMempool TerminallyUnderpriced InsufficientEth TxFeeExceedsCap // Note: L2FeeTooLow/L2FeeTooHigh/L2Full have a very specific meaning specific // to L2s (Arbitrum and clones). Do not implement this for non-L2 // chains. This is potentially confusing because some RPC nodes e.g. // Nethermind implement an error called `FeeTooLow` which has distinct // meaning from this one. L2FeeTooLow L2FeeTooHigh L2Full TransactionAlreadyMined Fatal TerminallyStuck TooManyResults ServiceTimeout )
const BALANCE_OF_ADDRESS_FUNCTION_SELECTOR = "0x70a08231"
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
const QueryTimeout = 10 * time.Second
const TerminallyStuckMsg = "transaction terminally stuck"
Variables ¶
This section is empty.
Functions ¶
func ClassifySendError ¶
func ClassifySendError(err error, clientErrors config.ClientErrors, lggr logger.SugaredLogger, tx *types.Transaction, fromAddress common.Address, isL2 bool) multinode.SendTxReturnCode
func FinalizeLatest ¶
FinalizeLatest commits new blocks until the latest block is finalized.
func FinalizeThroughBlock ¶
func FinalizeThroughBlock(t *testing.T, backend evmtypes.Backend, client HeadReader, blockNumber int64)
FinalizeThroughBlock commits new blocks until blockNumber is finalized. This requires committing all of the rest of the blocks in the epoch blockNumber belongs to, where each new epoch ends on a 32-block boundary (blockNumber % 32 == 0)
func IsTooManyResults ¶
func IsTooManyResults(err error, clientErrors config.ClientErrors) bool
func NewClientConfigs ¶
func NewClientConfigs( selectionMode *string, leaseDuration time.Duration, chainType string, nodeCfgs []NodeConfig, pollFailureThreshold *uint32, pollInterval time.Duration, syncThreshold *uint32, nodeIsSyncingEnabled *bool, noNewHeadsThreshold time.Duration, finalityDepth *uint32, finalityTagEnabled *bool, finalizedBlockOffset *uint32, enforceRepeatableRead *bool, deathDeclarationDelay time.Duration, noNewFinalizedHeadsThreshold time.Duration, finalizedBlockPollInterval time.Duration, newHeadsPollInterval time.Duration, ) (multinode.ChainConfig, evmconfig.NodePool, []*toml.Node, error)
Build the configs needed to initialize the chain client Parameters should only be basic go types to make it accessible for external users Configs can be stored in a variety of ways
func NewTxError ¶
func NewTxError(e error) commontypes.ErrorClassifier
func ToBackwardCompatibleBlockNumArg ¶
COPIED FROM go-ethereum/ethclient/gethclient - must be kept up to date!
func ToBackwardCompatibleCallArg ¶
func ToBackwardCompatibleCallArg(msg ethereum.CallMsg) interface{}
COPIED FROM go-ethereum/ethclient/gethclient - must be kept up to date! Modified to include legacy 'data' as well as 'input' in order to support non-compliant servers.
func ToBlockNumArg ¶
Types ¶
type CallArgs ¶
type CallArgs struct { From common.Address `json:"from"` 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. "From" is the sender address.
type Client ¶
type Client interface { Dial(ctx context.Context) error Close() // ChainID locally stored for quick access ConfiguredChainID() *big.Int // NodeStates returns a map of node Name->node state // It might be nil or empty, e.g. for mock clients etc NodeStates() map[string]string TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (*big.Int, error) BalanceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (*big.Int, error) LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*commonassets.Link, error) // Wrapped RPC methods CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error BatchCallContext(ctx context.Context, b []rpc.BatchElem) error // BatchCallContextAll calls BatchCallContext for every single node including // sendonlys. // CAUTION: This should only be used for mass re-transmitting transactions, it // might have unexpected effects to use it for anything else. BatchCallContextAll(ctx context.Context, b []rpc.BatchElem) error // HeadByNumber and HeadByHash is a reimplemented version due to a // difference in how block header hashes are calculated by Parity nodes // running on Kovan, Avalanche and potentially others. 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) HeadByHash(ctx context.Context, n common.Hash) (*evmtypes.Head, error) SubscribeToHeads(ctx context.Context) (<-chan *evmtypes.Head, ethereum.Subscription, error) // LatestFinalizedBlock - returns the latest finalized block as it's returned from an RPC. // CAUTION: Using this method might cause local finality violations. It's highly recommended // to use HeadTracker to get latest finalized block. LatestFinalizedBlock(ctx context.Context) (head *evmtypes.Head, err error) SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, fromAddress common.Address) (multinode.SendTxReturnCode, error) // Wrapped Geth client methods // blockNumber can be specified as `nil` to imply latest block // if blocks, transactions, or receipts are not found - a nil result and an error are returned // these methods may not be compatible with non Ethereum chains as return types may follow different formats // suggested options: use HeadByNumber/HeadByHash (above) or CallContext and parse with custom types SendTransaction(ctx context.Context, tx *types.Transaction) error CodeAt(ctx context.Context, account common.Address, blockNumber *big.Int) ([]byte, 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) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, error) TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, 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) SuggestGasTipCap(ctx context.Context) (*big.Int, error) LatestBlockHeight(ctx context.Context) (*big.Int, error) FeeHistory(ctx context.Context, blockCount uint64, lastBlock *big.Int, rewardPercentiles []float64) (feeHistory *ethereum.FeeHistory, err error) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error) HeaderByHash(ctx context.Context, h common.Hash) (*types.Header, error) CallContract(ctx context.Context, msg ethereum.CallMsg, blockNumber *big.Int) ([]byte, error) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error) IsL2() bool // Simulate the transaction prior to sending to catch zk out-of-counters errors ahead of time CheckTxValidity(ctx context.Context, from common.Address, to common.Address, data []byte) *SendError }
Client is the interface used to interact with an ethereum node.
func NewChainClient ¶
func NewChainClient( lggr logger.Logger, selectionMode string, leaseDuration time.Duration, nodes []multinode.Node[*big.Int, *RPCClient], sendonlys []multinode.SendOnlyNode[*big.Int, *RPCClient], chainID *big.Int, clientErrors evmconfig.ClientErrors, deathDeclarationDelay time.Duration, chainType chaintype.ChainType, ) Client
type ClientErrors ¶
func ClientErrorRegexes ¶
func ClientErrorRegexes(errsRegex config.ClientErrors) *ClientErrors
ClientErrorRegexes returns a map of compiled regexes for each error type
type HeadReader ¶
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 ¶
ExtractRPCError attempts to extract a full JsonError (including revert reason details) from an error returned by a CallContract to an external RPC. As per https://github.com/ethereum/go-ethereum/blob/c49e065fea78a5d3759f7853a608494913e5824e/internal/ethapi/api.go#L974 CallContract server side for a revert will return an error which contains either:
- The error directly from the EVM if there's no data (no revert reason, like an index out of bounds access) which when marshalled will only have a Message.
- An error which implements rpc.DataError which when marshalled will have a Data field containing the execution result. If the revert not a custom Error (solidity >= 0.8.0), like require(1 == 2, "revert"), then geth and forks will automatically parse the string and put it in the message. If its a custom error, it's up to the client to decode the Data field which will be the abi encoded data of the custom error, i.e. revert MyCustomError(10) -> keccak(MyCustomError(uint256))[:4] || abi.encode(10).
However, it appears that RPCs marshal this in different ways into a JsonError object received client side, some adding "Reverted" prefixes, removing the method signature etc. To avoid RPC specific parsing and support custom errors we return the full object returned from the RPC with a String() method that stringifies all fields for logging so no information is lost. Some examples: kovan (parity) { "error": { "code" : -32015, "data": "Reverted 0xABC123...", "message": "VM execution error." } } // revert reason always omitted from message. rinkeby / ropsten (geth) { "error": { "code": 3, "data": "0xABC123...", "message": "execution reverted: hello world" } } // revert reason automatically parsed if a simple require and included in message.
func ExtractRPCErrorOrNil ¶
type NodeConfig ¶
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) BatchCallContext ¶
func (*NullClient) BatchCallContextAll ¶
BatchCallContextAll implements evmclient.Client interface
func (*NullClient) BlockByHash ¶
func (*NullClient) BlockByNumber ¶
func (*NullClient) CallContext ¶
func (nc *NullClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
func (*NullClient) CallContract ¶
func (*NullClient) CheckTxValidity ¶
func (*NullClient) Close ¶
func (nc *NullClient) Close()
func (*NullClient) ConfiguredChainID ¶
func (nc *NullClient) ConfiguredChainID() *big.Int
func (*NullClient) EstimateGas ¶
func (nc *NullClient) EstimateGas(ctx context.Context, call ethereum.CallMsg) (uint64, error)
func (*NullClient) FeeHistory ¶
func (*NullClient) FilterLogs ¶
func (*NullClient) HeadByHash ¶
func (*NullClient) HeadByNumber ¶
func (*NullClient) HeaderByHash ¶
func (*NullClient) HeaderByNumber ¶
func (*NullClient) IsL2 ¶
func (nc *NullClient) IsL2() bool
func (*NullClient) LINKBalance ¶
func (*NullClient) LatestBlockHeight ¶
func (*NullClient) LatestFinalizedBlock ¶
func (*NullClient) NodeStates ¶
func (nc *NullClient) NodeStates() map[string]string
NodeStates implements evmclient.Client
func (*NullClient) PendingCallContract ¶
func (nc *NullClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error)
func (*NullClient) PendingCodeAt ¶
func (*NullClient) PendingNonceAt ¶
func (*NullClient) SendTransaction ¶
func (nc *NullClient) SendTransaction(ctx context.Context, tx *types.Transaction) error
func (*NullClient) SendTransactionReturnCode ¶
func (nc *NullClient) SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, sender common.Address) (multinode.SendTxReturnCode, error)
func (*NullClient) SubscribeFilterLogs ¶
func (*NullClient) SubscribeToHeads ¶
func (*NullClient) SuggestGasPrice ¶
func (*NullClient) SuggestGasTipCap ¶
func (*NullClient) TokenBalance ¶
func (*NullClient) TransactionByHash ¶
func (nc *NullClient) TransactionByHash(ctx context.Context, txHash common.Hash) (*types.Transaction, error)
func (*NullClient) TransactionReceipt ¶
type RPCClient ¶
type RPCClient struct { *multinode.RPCClientBase[*evmtypes.Head] // contains filtered or unexported fields }
func NewRPCClient ¶
func (*RPCClient) BatchCallContext ¶
func (*RPCClient) BlockByHash ¶
func (*RPCClient) BlockByHashGeth ¶
func (*RPCClient) BlockByNumber ¶
func (*RPCClient) BlockByNumberGeth ¶
func (*RPCClient) BlockNumber ¶
func (*RPCClient) CallContext ¶
func (r *RPCClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error
CallContext implementation
func (*RPCClient) CallContract ¶
func (*RPCClient) ChainID ¶
Returns the ChainID according to the geth client. This is useful for functions like verify() the common node.
func (*RPCClient) ClientVersion ¶
func (*RPCClient) DialHTTP ¶
DialHTTP doesn't actually make any external HTTP calls It can only return error if the URL is malformed.
func (*RPCClient) EstimateGas ¶
func (*RPCClient) FeeHistory ¶
func (*RPCClient) FilterEvents ¶
func (*RPCClient) FilterLogs ¶
func (*RPCClient) HeaderByHash ¶
func (*RPCClient) HeaderByNumber ¶
func (*RPCClient) LINKBalance ¶
func (r *RPCClient) LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*commonassets.Link, error)
LINKBalance returns the balance of LINK at the given address
func (*RPCClient) LatestBlockHeight ¶
func (*RPCClient) NonceAt ¶
func (r *RPCClient) NonceAt(ctx context.Context, account common.Address, blockNumber *big.Int) (nonce uint64, err error)
NonceAt is a bit of a misnomer. You might expect it to return the highest mined nonce at the given block number, but it actually returns the total transaction count which is the highest mined nonce + 1
func (*RPCClient) PendingCallContract ¶
func (*RPCClient) PendingCodeAt ¶
func (*RPCClient) PendingSequenceAt ¶
func (r *RPCClient) PendingSequenceAt(ctx context.Context, account common.Address) (nonce evmtypes.Nonce, err error)
PendingSequenceAt returns one higher than the highest nonce from both mempool and mined transactions
func (*RPCClient) SendEmptyTransaction ¶
func (r *RPCClient) SendEmptyTransaction( ctx context.Context, newTxAttempt func(nonce evmtypes.Nonce, feeLimit uint32, fee *assets.Wei, fromAddress common.Address) (attempt any, err error), nonce evmtypes.Nonce, gasLimit uint32, fee *assets.Wei, fromAddress common.Address, ) (txhash string, err error)
func (*RPCClient) SendTransaction ¶
func (r *RPCClient) SendTransaction(ctx context.Context, tx *types.Transaction) (struct{}, multinode.SendTxReturnCode, error)
func (*RPCClient) SimulateTransaction ¶
func (*RPCClient) SubscribeFilterLogs ¶
func (*RPCClient) SubscribeToHeads ¶
func (r *RPCClient) SubscribeToHeads(ctx context.Context) (ch <-chan *evmtypes.Head, sub multinode.Subscription, err error)
SubscribeToHeads implements custom SubscribeToheads method to override the RPCClientBase with added ws support.
func (*RPCClient) SuggestGasPrice ¶
func (*RPCClient) SuggestGasTipCap ¶
func (*RPCClient) TokenBalance ¶
func (r *RPCClient) TokenBalance(ctx context.Context, address common.Address, contractAddress common.Address) (*big.Int, error)
TokenBalance returns the balance of the given address for the token contract address.
func (*RPCClient) TransactionByHash ¶
func (*RPCClient) TransactionReceipt ¶
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 NewSendError ¶
func NewSendErrorS ¶
func SimulateTransaction ¶
func SimulateTransaction(ctx context.Context, client simulatorClient, lggr logger.SugaredLogger, chainType chaintype.ChainType, msg ethereum.CallMsg) *SendError
ZK chains can return an out-of-counters error This method allows a caller to determine if a tx would fail due to OOC error by simulating the transaction Used as an entry point in case custom simulation is required across different chains
func (*SendError) Fatal ¶
func (s *SendError) Fatal(configErrors *ClientErrors) 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) IsCanceled ¶
IsCanceled indicates if the error was caused by an context cancellation
func (*SendError) IsFatal ¶
IsFatal indicates if a transaction error is considered fatal for external callers The naming discrepancy is due to the generic transaction statuses introduced by ChainWriter
func (*SendError) IsInsufficientEth ¶
func (s *SendError) IsInsufficientEth(configErrors *ClientErrors) bool
func (*SendError) IsL2FeeTooHigh ¶
func (s *SendError) IsL2FeeTooHigh(configErrors *ClientErrors) bool
IsL2FeeTooHigh is an l2-specific error returned when total fee is too high
func (*SendError) IsL2Full ¶
func (s *SendError) IsL2Full(configErrors *ClientErrors) bool
IsL2Full is an l2-specific error returned when the queue or mempool is full.
func (*SendError) IsNonceTooHighError ¶
func (s *SendError) IsNonceTooHighError(configErrors *ClientErrors) bool
func (*SendError) IsNonceTooLowError ¶
func (s *SendError) IsNonceTooLowError(configErrors *ClientErrors) bool
func (*SendError) IsReplacementUnderpriced ¶
func (s *SendError) IsReplacementUnderpriced(configErrors *ClientErrors) bool
IsReplacementUnderpriced indicates that a transaction already exists in the mempool with this nonce but a different gas price or payload
func (*SendError) IsServiceTimeout ¶
func (s *SendError) IsServiceTimeout(configErrors *ClientErrors) bool
IsServiceTimeout indicates if the error was caused by a service timeout
func (*SendError) IsServiceUnavailable ¶
func (s *SendError) IsServiceUnavailable(configErrors *ClientErrors) bool
IsServiceUnavailable indicates if the error was caused by a service being unavailable
func (*SendError) IsTemporarilyUnderpriced ¶
func (s *SendError) IsTemporarilyUnderpriced(configErrors *ClientErrors) bool
func (*SendError) IsTerminallyStuckConfigError ¶
func (s *SendError) IsTerminallyStuckConfigError(configErrors *ClientErrors) bool
IsTerminallyStuck indicates if a transaction was stuck without any chance of inclusion
func (*SendError) IsTerminallyUnderpriced ¶
func (s *SendError) IsTerminallyUnderpriced(configErrors *ClientErrors) bool
IsTerminallyUnderpriced indicates that this transaction is so far underpriced the node won't even accept it in the first place
func (*SendError) IsTimeout ¶
IsTimeout indicates if the error was caused by an exceeded context deadline
func (*SendError) IsTransactionAlreadyInMempool ¶
func (s *SendError) IsTransactionAlreadyInMempool(configErrors *ClientErrors) bool
Geth/parity returns this error if the transaction is already in the node's mempool
func (*SendError) IsTransactionAlreadyMined ¶
func (s *SendError) IsTransactionAlreadyMined(configErrors *ClientErrors) bool
IsTransactionAlreadyMined - Harmony returns this error if the transaction has already been mined
func (*SendError) IsTxFeeExceedsCap ¶
func (s *SendError) IsTxFeeExceedsCap(configErrors *ClientErrors) bool
IsTxFeeExceedsCap 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) L2FeeTooLow ¶
func (s *SendError) L2FeeTooLow(configErrors *ClientErrors) bool
L2FeeTooLow is an l2-specific error returned when total fee is too low
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 evmtypes.Backend, chainID *big.Int) *SimulatedBackendClient
NewSimulatedBackendClient creates an eth client backed by a simulated backend.
func (*SimulatedBackendClient) Backend ¶
func (c *SimulatedBackendClient) Backend() evmtypes.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 ¶
BatchCallContext makes a batch rpc call. The simulated client avoids the old block error from the simulated backend by passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext` and will not return an error when an old block is used.
func (*SimulatedBackendClient) BatchCallContextAll ¶
BatchCallContextAll makes a batch rpc call.
func (*SimulatedBackendClient) BlockByHash ¶
func (c *SimulatedBackendClient) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error)
BlockByNumber returns a geth block type.
func (*SimulatedBackendClient) BlockByNumber ¶
func (c *SimulatedBackendClient) BlockByNumber(ctx context.Context, n *big.Int) (*types.Block, error)
BlockByNumber returns a geth block type.
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. The simulated client avoids the old block error from the simulated backend by passing `nil` to `CallContract` when calling `CallContext` or `BatchCallContext` and will not return an error when an old block is used.
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, error)
ChainID RPC call
func (*SimulatedBackendClient) CheckTxValidity ¶
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) Commit ¶
func (c *SimulatedBackendClient) Commit() common.Hash
Commit imports all the pending transactions as a single block and starts a fresh new state.
func (*SimulatedBackendClient) ConfiguredChainID ¶
func (c *SimulatedBackendClient) ConfiguredChainID() *big.Int
ChainID returns the ethereum ChainID.
func (*SimulatedBackendClient) Dial ¶
func (c *SimulatedBackendClient) Dial(context.Context) error
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) FeeHistory ¶
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) HeadByHash ¶
func (c *SimulatedBackendClient) HeadByHash(ctx context.Context, h common.Hash) (*evmtypes.Head, error)
HeadByHash returns our own header type.
func (*SimulatedBackendClient) HeadByNumber ¶
func (c *SimulatedBackendClient) HeadByNumber(ctx context.Context, n *big.Int) (*evmtypes.Head, error)
HeadByNumber returns our own header type.
func (*SimulatedBackendClient) HeaderByHash ¶
func (*SimulatedBackendClient) HeaderByNumber ¶
func (c *SimulatedBackendClient) HeaderByNumber(ctx context.Context, n *big.Int) (*types.Header, error)
HeaderByNumber returns the geth header type.
func (*SimulatedBackendClient) IsL2 ¶
func (c *SimulatedBackendClient) IsL2() bool
func (*SimulatedBackendClient) LINKBalance ¶
func (c *SimulatedBackendClient) LINKBalance(ctx context.Context, address common.Address, linkAddress common.Address) (*assets.Link, error)
GetLINKBalance get link balance.
func (*SimulatedBackendClient) LatestBlockHeight ¶
func (*SimulatedBackendClient) LatestFinalizedBlock ¶
func (*SimulatedBackendClient) NodeStates ¶
func (c *SimulatedBackendClient) NodeStates() map[string]string
NodeStates implements evmclient.Client
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) PendingCallContract ¶
func (c *SimulatedBackendClient) PendingCallContract(ctx context.Context, msg ethereum.CallMsg) ([]byte, error)
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) RegisterHeadByNumberCallback ¶
func (c *SimulatedBackendClient) RegisterHeadByNumberCallback(cb func(ctx context.Context, c *SimulatedBackendClient, n *big.Int) error)
func (*SimulatedBackendClient) SendTransaction ¶
func (c *SimulatedBackendClient) SendTransaction(ctx context.Context, tx *types.Transaction) error
SendTransaction sends a transaction.
func (*SimulatedBackendClient) SendTransactionReturnCode ¶
func (c *SimulatedBackendClient) SendTransactionReturnCode(ctx context.Context, tx *types.Transaction, fromAddress common.Address) (multinode.SendTxReturnCode, error)
func (*SimulatedBackendClient) SetBackend ¶
func (c *SimulatedBackendClient) SetBackend(backend evmtypes.Backend, chainType chaintype.ChainType)
Switch to a new backend client (simulating an rpc failover event) If chainFamily = Optimism, the new backend will exhibit the non-geth behavior of optimism (and some other rpc clients), where success rather than an error code is returned when a call to FilterLogs() fails to find the block hash requested. This combined with a failover event can lead to the "eventual consistency" behavior that Backup LogPoller and other solutions were designed to recover from.
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) SubscribeToHeads ¶
func (c *SimulatedBackendClient) SubscribeToHeads( ctx context.Context, ) (<-chan *evmtypes.Head, ethereum.Subscription, error)
SubscribeToHeads 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 ¶
SuggestGasPrice recommends a gas price.
func (*SimulatedBackendClient) SuggestGasTipCap ¶
SuggestGasTipCap suggests a gas tip cap.
func (*SimulatedBackendClient) TokenBalance ¶
func (*SimulatedBackendClient) TransactionByHash ¶
func (c *SimulatedBackendClient) TransactionByHash(ctx context.Context, txHash common.Hash) (tx *types.Transaction, err error)
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.