blockchain

package
v1.1.19 Latest Latest
Warning

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

Go to latest
Published: May 7, 2022 License: MIT Imports: 22 Imported by: 25

README

Blockchain Clients

Contains code to connect and command blockchains

Documentation

Overview

Package blockchain handles connections to various blockchains

Index

Constants

View Source
const (
	SimulatedEthNetwork   = "eth_simulated"
	LiveEthTestNetwork    = "eth_testnet"
	LiveKlaytnTestNetwork = "klaytn_testnet"
	LiveMetisTestNetwork  = "metis_testnet"
)

Commonly used blockchain network types

View Source
const (
	// GWei one giga-wei used for gas calculations
	GWei = 1e9
	// ETH one eth in wei
	ETH = 1e18
)

Variables

This section is empty.

Functions

func LiveEthTestnetURLs

func LiveEthTestnetURLs(e *environment.Environment) ([]*url.URL, error)

LiveEthTestnetURLs indicates that there are no urls to fetch, except from the network config

func SimulatedEthereumURLs

func SimulatedEthereumURLs(e *environment.Environment) ([]*url.URL, error)

SimulatedEthereumURLs returns the websocket URLs for a simulated geth network

func SimulatedSoakEthereumURLs

func SimulatedSoakEthereumURLs(e *environment.Environment) ([]*url.URL, error)

SimulatedEthereumURLs returns the websocket URLs for a simulated geth network

func UnmarshalNetworkConfig

func UnmarshalNetworkConfig(config map[string]interface{}, obj interface{}) error

UnmarshalNetworkConfig is a generic function to unmarshal a yaml map into a given object

Types

type ClientURLFn

type ClientURLFn func(e *environment.Environment) ([]*url.URL, error)

ClientURLFn are used to be able to return a list of URLs from the environment to connect

type ContractDeployer

type ContractDeployer func(auth *bind.TransactOpts, backend bind.ContractBackend) (
	common.Address,
	*types.Transaction,
	interface{},
	error,
)

ContractDeployer acts as a go-between function for general contract deployment

type EVMClient

type EVMClient interface {
	// Getters
	Get() interface{}
	GetNetworkName() string
	GetNetworkType() string
	GetChainID() *big.Int
	GetClients() []EVMClient
	GetDefaultWallet() *EthereumWallet
	GetWallets() []*EthereumWallet
	GetNetworkConfig() *config.ETHNetwork

	// Setters
	SetID(id int)
	SetDefaultWallet(num int) error
	SetWallets([]*EthereumWallet)
	LoadWallets(ns interface{}) error
	SwitchNode(node int) error

	// On-chain Operations
	HeaderHashByNumber(ctx context.Context, bn *big.Int) (string, error)
	HeaderTimestampByNumber(ctx context.Context, bn *big.Int) (uint64, error)
	LatestBlockNumber(ctx context.Context) (uint64, error)
	Fund(toAddress string, amount *big.Float) error
	DeployContract(
		contractName string,
		deployer ContractDeployer,
	) (*common.Address, *types.Transaction, interface{}, error)
	TransactionOpts(from *EthereumWallet) (*bind.TransactOpts, error)
	ProcessTransaction(tx *types.Transaction) error
	IsTxConfirmed(txHash common.Hash) (bool, error)
	ParallelTransactions(enabled bool)
	Close() error

	// Gas Operations
	EstimateCostForChainlinkOperations(amountOfOperations int) (*big.Float, error)
	EstimateTransactionGasCost() (*big.Int, error)
	GasStats() *GasStats

	// Event Subscriptions
	AddHeaderEventSubscription(key string, subscriber HeaderEventSubscription)
	DeleteHeaderEventSubscription(key string)
	WaitForEvents() error
}

EVMClient is the interface that wraps a given client implementation for a blockchain, to allow for switching of network types within the test suite EVMClient can be connected to a single or multiple nodes,

func NewEthereumClient

func NewEthereumClient(networkSettings *config.ETHNetwork) (EVMClient, error)

NewEthereumClient returns an instantiated instance of the Ethereum client that has connected to the server

func NewEthereumMultiNodeClient

func NewEthereumMultiNodeClient(
	_ string,
	networkConfig map[string]interface{},
	urls []*url.URL,
) (EVMClient, error)

NewEthereumMultiNodeClient returns an instantiated instance of all Ethereum client connected to all nodes

func NewKlaytnClient

func NewKlaytnClient(networkSettings *config.ETHNetwork) (EVMClient, error)

NewKlaytnClient returns an instantiated instance of the Klaytn client that has connected to the server

func NewKlaytnMultiNodeClient

func NewKlaytnMultiNodeClient(
	_ string,
	networkConfig map[string]interface{},
	urls []*url.URL,
) (EVMClient, error)

NewKlaytnMultiNodeClient returns an instantiated instance of all Klaytn clients connected to all nodes

func NewMetisClient

func NewMetisClient(networkSettings *config.ETHNetwork) (EVMClient, error)

NewMetisClient returns an instantiated instance of the Metis client that has connected to the server

func NewMetisMultiNodeClient

func NewMetisMultiNodeClient(
	_ string,
	networkConfig map[string]interface{},
	urls []*url.URL,
) (EVMClient, error)

NewMetisMultinodeClient returns an instantiated instance of all Metis clients connected to all nodes

type EthereumClient

type EthereumClient struct {
	ID            int
	Client        *ethclient.Client
	NetworkConfig *config.ETHNetwork
	Wallets       []*EthereumWallet
	DefaultWallet *EthereumWallet
	BorrowNonces  bool
	NonceMu       *sync.Mutex
	Nonces        map[string]uint64
	// contains filtered or unexported fields
}

EthereumClient wraps the client and the BlockChain network to interact with an EVM based Blockchain

func (*EthereumClient) AddHeaderEventSubscription

func (e *EthereumClient) AddHeaderEventSubscription(key string, subscriber HeaderEventSubscription)

AddHeaderEventSubscription adds a new header subscriber within the client to receive new headers

func (*EthereumClient) BorrowedNonces

func (e *EthereumClient) BorrowedNonces(n bool)

BorrowedNonces allows to handle nonces concurrently without requesting them every time

func (*EthereumClient) Close

func (e *EthereumClient) Close() error

Close tears down the current open Ethereum client

func (*EthereumClient) DeleteHeaderEventSubscription

func (e *EthereumClient) DeleteHeaderEventSubscription(key string)

DeleteHeaderEventSubscription removes a header subscriber from the map

func (*EthereumClient) DeployContract

func (e *EthereumClient) DeployContract(
	contractName string,
	deployer ContractDeployer,
) (*common.Address, *types.Transaction, interface{}, error)

DeployContract acts as a general contract deployment tool to an ethereum chain

func (*EthereumClient) EstimateCostForChainlinkOperations

func (e *EthereumClient) EstimateCostForChainlinkOperations(amountOfOperations int) (*big.Float, error)

EstimateCostForChainlinkOperations calculates required amount of ETH for amountOfOperations Chainlink operations based on the network's suggested gas price and the chainlink gas limit. This is fairly imperfect and should be used as only a rough, upper-end estimate instead of an exact calculation. See https://ethereum.org/en/developers/docs/gas/#post-london for info on how gas calculation works

func (*EthereumClient) EstimateTransactionGasCost

func (e *EthereumClient) EstimateTransactionGasCost() (*big.Int, error)

EstimateTransactionGasCost estimates the current total gas cost for a simple transaction

func (*EthereumClient) Fund

func (e *EthereumClient) Fund(
	toAddress string,
	amount *big.Float,
) error

Fund sends some ETH to an address using the default wallet

func (*EthereumClient) GasStats

func (e *EthereumClient) GasStats() *GasStats

GasStats retrieves all information on gas spent by this client

func (*EthereumClient) Get

func (e *EthereumClient) Get() interface{}

Get returns the underlying client type to be used generically across the framework for switching network types

func (*EthereumClient) GetChainID

func (e *EthereumClient) GetChainID() *big.Int

GetChainID retrieves the ChainID of the network that the client interacts with

func (*EthereumClient) GetClients

func (e *EthereumClient) GetClients() []EVMClient

GetClients not used, only applicable to EthereumMultinodeClient

func (*EthereumClient) GetDefaultWallet

func (e *EthereumClient) GetDefaultWallet() *EthereumWallet

DefaultWallet returns the default wallet for the network

func (*EthereumClient) GetHeaderSubscriptions

func (e *EthereumClient) GetHeaderSubscriptions() map[string]HeaderEventSubscription

GetHeaderSubscriptions returns a duplicate map of the queued transactions

func (*EthereumClient) GetNetworkConfig

func (e *EthereumClient) GetNetworkConfig() *config.ETHNetwork

DefaultWallet returns the default wallet for the network

func (*EthereumClient) GetNetworkName

func (e *EthereumClient) GetNetworkName() string

GetNetworkName retrieves the ID of the network that the client interacts with

func (*EthereumClient) GetNetworkType

func (e *EthereumClient) GetNetworkType() string

GetNetworkType retrieves the type of network this is running on

func (*EthereumClient) GetNonce

func (e *EthereumClient) GetNonce(ctx context.Context, addr common.Address) (uint64, error)

GetNonce keep tracking of nonces per address, add last nonce for addr if the map is empty

func (*EthereumClient) GetWallets

func (e *EthereumClient) GetWallets() []*EthereumWallet

DefaultWallet returns the default wallet for the network

func (*EthereumClient) HeaderHashByNumber

func (e *EthereumClient) HeaderHashByNumber(ctx context.Context, bn *big.Int) (string, error)

HeaderHashByNumber gets header hash by block number

func (*EthereumClient) HeaderTimestampByNumber

func (e *EthereumClient) HeaderTimestampByNumber(ctx context.Context, bn *big.Int) (uint64, error)

HeaderTimestampByNumber gets header timestamp by number

func (*EthereumClient) IsTxConfirmed

func (e *EthereumClient) IsTxConfirmed(txHash common.Hash) (bool, error)

IsTxConfirmed checks if the transaction is confirmed on chain or not

func (*EthereumClient) LatestBlockNumber

func (e *EthereumClient) LatestBlockNumber(ctx context.Context) (uint64, error)

BlockNumber gets latest block number

func (*EthereumClient) LoadWallets

func (e *EthereumClient) LoadWallets(cfg interface{}) error

LoadWallets loads wallets from config

func (*EthereumClient) ParallelTransactions

func (e *EthereumClient) ParallelTransactions(enabled bool)

ParallelTransactions when enabled, sends the transaction without waiting for transaction confirmations. The hashes are then stored within the client and confirmations can be waited on by calling WaitForEvents. When disabled, the minimum confirmations are waited on when the transaction is sent, so parallelisation is disabled.

func (*EthereumClient) ProcessTransaction

func (e *EthereumClient) ProcessTransaction(tx *types.Transaction) error

ProcessTransaction will queue or wait on a transaction depending on whether parallel transactions are enabled

func (*EthereumClient) SetDefaultWallet

func (e *EthereumClient) SetDefaultWallet(num int) error

SetDefaultWallet sets default wallet

func (*EthereumClient) SetID

func (e *EthereumClient) SetID(id int)

SetID sets client id, only used for multi-node networks

func (*EthereumClient) SetWallets

func (e *EthereumClient) SetWallets(wallets []*EthereumWallet)

SetWallets sets all wallets to be used by the client

func (*EthereumClient) SwitchNode

func (e *EthereumClient) SwitchNode(_ int) error

SwitchNode not used, only applicable to EthereumMultinodeClient

func (*EthereumClient) TransactionOpts

func (e *EthereumClient) TransactionOpts(from *EthereumWallet) (*bind.TransactOpts, error)

TransactionOpts returns the base Tx options for 'transactions' that interact with a smart contract. Since most contract interactions in this framework are designed to happen through abigen calls, it's intentionally quite bare.

func (*EthereumClient) WaitForEvents

func (e *EthereumClient) WaitForEvents() error

WaitForEvents is a blocking function that waits for all event subscriptions that have been queued within the client.

type EthereumMultinodeClient

type EthereumMultinodeClient struct {
	DefaultClient EVMClient
	Clients       []EVMClient
}

EthereumMultinodeClient wraps the client and the BlockChain network to interact with an EVM based Blockchain with multiple nodes

func (*EthereumMultinodeClient) AddHeaderEventSubscription

func (e *EthereumMultinodeClient) AddHeaderEventSubscription(key string, subscriber HeaderEventSubscription)

AddHeaderEventSubscription adds a new header subscriber within the client to receive new headers

func (*EthereumMultinodeClient) Close

func (e *EthereumMultinodeClient) Close() error

Close tears down the all the clients

func (*EthereumMultinodeClient) DeleteHeaderEventSubscription

func (e *EthereumMultinodeClient) DeleteHeaderEventSubscription(key string)

DeleteHeaderEventSubscription removes a header subscriber from the map

func (*EthereumMultinodeClient) DeployContract

func (e *EthereumMultinodeClient) DeployContract(
	contractName string,
	deployer ContractDeployer,
) (*common.Address, *types.Transaction, interface{}, error)

Fund funds a specified address with LINK token and or ETH from the given wallet

func (*EthereumMultinodeClient) EstimateCostForChainlinkOperations

func (e *EthereumMultinodeClient) EstimateCostForChainlinkOperations(amountOfOperations int) (*big.Float, error)

EstimateCostForChainlinkOperations calculates TXs cost as a dirty estimation based on transactionLimit for that network

func (*EthereumMultinodeClient) EstimateTransactionGasCost

func (e *EthereumMultinodeClient) EstimateTransactionGasCost() (*big.Int, error)

func (*EthereumMultinodeClient) Fund

func (e *EthereumMultinodeClient) Fund(toAddress string, nativeAmount *big.Float) error

Fund funds a specified address with LINK token and or ETH from the given wallet

func (*EthereumMultinodeClient) GasStats

func (e *EthereumMultinodeClient) GasStats() *GasStats

GasStats gets gas stats instance

func (*EthereumMultinodeClient) Get

func (e *EthereumMultinodeClient) Get() interface{}

Get gets default client as an interface{}

func (*EthereumMultinodeClient) GetChainID

func (e *EthereumMultinodeClient) GetChainID() *big.Int

GetChainID retrieves the ChainID of the network that the client interacts with

func (*EthereumMultinodeClient) GetClients

func (e *EthereumMultinodeClient) GetClients() []EVMClient

GetClients gets clients for all nodes connected

func (*EthereumMultinodeClient) GetDefaultWallet

func (e *EthereumMultinodeClient) GetDefaultWallet() *EthereumWallet

GetDefaultWallet returns the default wallet for the network

func (*EthereumMultinodeClient) GetNetworkConfig

func (e *EthereumMultinodeClient) GetNetworkConfig() *config.ETHNetwork

GetDefaultWallet returns the default wallet for the network

func (*EthereumMultinodeClient) GetNetworkName

func (e *EthereumMultinodeClient) GetNetworkName() string

GetNetworkName gets the ID of the chain that the clients are connected to

func (*EthereumMultinodeClient) GetNetworkType

func (e *EthereumMultinodeClient) GetNetworkType() string

GetNetworkType retrieves the type of network this is running on

func (*EthereumMultinodeClient) GetWallets

func (e *EthereumMultinodeClient) GetWallets() []*EthereumWallet

GetDefaultWallet returns the default wallet for the network

func (*EthereumMultinodeClient) HeaderHashByNumber

func (e *EthereumMultinodeClient) HeaderHashByNumber(ctx context.Context, bn *big.Int) (string, error)

HeaderHashByNumber gets header hash by block number

func (*EthereumMultinodeClient) HeaderTimestampByNumber

func (e *EthereumMultinodeClient) HeaderTimestampByNumber(ctx context.Context, bn *big.Int) (uint64, error)

HeaderTimestampByNumber gets header timestamp by number

func (*EthereumMultinodeClient) IsTxConfirmed

func (e *EthereumMultinodeClient) IsTxConfirmed(txHash common.Hash) (bool, error)

IsTxConfirmed returns the default client's transaction confirmations

func (*EthereumMultinodeClient) LatestBlockNumber

func (e *EthereumMultinodeClient) LatestBlockNumber(ctx context.Context) (uint64, error)

LatestBlockNumber gets the latest block number from the default client

func (*EthereumMultinodeClient) LoadWallets

func (e *EthereumMultinodeClient) LoadWallets(cfg interface{}) error

LoadWallets loads wallets using private keys provided in the config

func (*EthereumMultinodeClient) ParallelTransactions

func (e *EthereumMultinodeClient) ParallelTransactions(enabled bool)

ParallelTransactions when enabled, sends the transaction without waiting for transaction confirmations. The hashes are then stored within the client and confirmations can be waited on by calling WaitForEvents. When disabled, the minimum confirmations are waited on when the transaction is sent, so parallelisation is disabled.

func (*EthereumMultinodeClient) ProcessTransaction

func (e *EthereumMultinodeClient) ProcessTransaction(tx *types.Transaction) error

ProcessTransaction returns the result of the default client's processed transaction

func (*EthereumMultinodeClient) SetDefaultWallet

func (e *EthereumMultinodeClient) SetDefaultWallet(num int) error

SetDefaultWallet sets default wallet

func (*EthereumMultinodeClient) SetID

func (e *EthereumMultinodeClient) SetID(id int)

SetID sets client ID in a multi-node environment

func (*EthereumMultinodeClient) SetWallets

func (e *EthereumMultinodeClient) SetWallets(wallets []*EthereumWallet)

SetWallets sets the default client's wallets

func (*EthereumMultinodeClient) SwitchNode

func (e *EthereumMultinodeClient) SwitchNode(clientID int) error

SwitchNode sets default client to perform calls to the network

func (*EthereumMultinodeClient) TransactionOpts

func (e *EthereumMultinodeClient) TransactionOpts(from *EthereumWallet) (*bind.TransactOpts, error)

TransactionOpts returns the base Tx options for 'transactions' that interact with a smart contract. Since most contract interactions in this framework are designed to happen through abigen calls, it's intentionally quite bare.

func (*EthereumMultinodeClient) WaitForEvents

func (e *EthereumMultinodeClient) WaitForEvents() error

WaitForEvents is a blocking function that waits for all event subscriptions for all clients

type EthereumWallet

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

EthereumWallet is the implementation to allow testing with ETH based wallets

func NewEthereumWallet

func NewEthereumWallet(pk string) (*EthereumWallet, error)

NewEthereumWallet returns the instantiated ETH wallet based on a given private key

func (*EthereumWallet) Address

func (e *EthereumWallet) Address() string

Address returns the ETH address for a given wallet

func (*EthereumWallet) PrivateKey

func (e *EthereumWallet) PrivateKey() string

PrivateKey returns the private key for a given Ethereum wallet

func (*EthereumWallet) RawPrivateKey

func (e *EthereumWallet) RawPrivateKey() interface{}

RawPrivateKey returns raw private key if it has some encoding or in bytes

type GasStats

type GasStats struct {
	NodeID       int
	TotalGasUsed int64
	SeenHashes   map[string]bool
	ClientTXs    []TXGasData
}

GasStats helper struct to determine gas metrics across all txs of a test

func NewGasStats

func NewGasStats(nodeID int) *GasStats

NewGasStats creates new gas stats collector

func (*GasStats) AddClientTXData

func (g *GasStats) AddClientTXData(data TXGasData)

AddClientTXData adds client TX data

func (*GasStats) PrintStats

func (g *GasStats) PrintStats()

PrintStats prints gas stats and total TXs cost

type HeaderEventSubscription

type HeaderEventSubscription interface {
	ReceiveBlock(header NodeBlock) error
	Wait() error
}

HeaderEventSubscription is an interface for allowing callbacks when the client receives a new header

type InstantConfirmations

type InstantConfirmations struct{}

InstantConfirmations is a no-op confirmer as all transactions are instantly mined so no confirmations are needed

func (*InstantConfirmations) ReceiveBlock

func (i *InstantConfirmations) ReceiveBlock(block NodeBlock) error

ReceiveBlock is a no-op

func (*InstantConfirmations) Wait

func (i *InstantConfirmations) Wait() error

Wait is a no-op

type KlaytnClient

type KlaytnClient struct {
	*EthereumClient
}

KlaytnClient represents a single node, EVM compatible client for the Klaytn network

func (*KlaytnClient) DeployContract

func (k *KlaytnClient) DeployContract(
	contractName string,
	deployer ContractDeployer,
) (*common.Address, *types.Transaction, interface{}, error)

DeployContract acts as a general contract deployment tool to an ethereum chain

func (*KlaytnClient) Fund

func (k *KlaytnClient) Fund(
	toAddress string,
	amount *big.Float,
) error

Fund overrides ethereum's fund to account for Klaytn's gas specifications https://docs.klaytn.com/klaytn/design/transaction-fees#unit-price

type KlaytnMultinodeClient

type KlaytnMultinodeClient struct {
	*EthereumMultinodeClient
}

KlaytnMultinodeClient represents a multi-node, EVM compatible client for the Klaytn network

type MetisClient

type MetisClient struct {
	*EthereumClient
}

MetisClient represents a single node, EVM compatible client for the Metis network

func (*MetisClient) DeployContract

func (m *MetisClient) DeployContract(
	contractName string,
	deployer ContractDeployer,
) (*common.Address, *types.Transaction, interface{}, error)

DeployContract acts as a general contract deployment tool to an EVM chain

func (*MetisClient) Fund

func (m *MetisClient) Fund(toAddress string, amount *big.Float) error

Fund sends some ETH to an address using the default wallet

type MetisMultinodeClient

type MetisMultinodeClient struct {
	*EthereumMultinodeClient
}

MetisMultinodeClient represents a multi-node, EVM compatible client for the Metis network

type NetworkRegistry

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

NetworkRegistry holds all the registered network types that can be initialized, allowing external libraries to register alternative network types to use

func NewDefaultNetworkRegistry

func NewDefaultNetworkRegistry() *NetworkRegistry

NewDefaultNetworkRegistry returns an instance of the network registry with the default supported networks registered

func NewSoakNetworkRegistry

func NewSoakNetworkRegistry() *NetworkRegistry

NewSoakNetworkRegistry retrieves a network registry for use in soak tests

func (*NetworkRegistry) GetNetworks

func (n *NetworkRegistry) GetNetworks(env *environment.Environment) (*Networks, error)

GetNetworks returns a networks object with all the BlockchainClient(s) initialized

func (*NetworkRegistry) RegisterNetwork

func (n *NetworkRegistry) RegisterNetwork(networkType string, fn NewEVMClientFn, urlFn ClientURLFn)

RegisterNetwork registers a new type of network within the registry

type Networks

type Networks struct {
	Default EVMClient
	// contains filtered or unexported fields
}

Networks is a thin wrapper that just selects client connected to some network if there is only one client it is chosen as Default if there is multiple you just get clients you need in test

func (*Networks) AllNetworks

func (b *Networks) AllNetworks() []EVMClient

AllNetworks returns all the network clients

func (*Networks) Get

func (b *Networks) Get(index int) (EVMClient, error)

Get gets blockchain network (client) by name

func (*Networks) SetDefault

func (b *Networks) SetDefault(index int) error

SetDefault chooses default client

func (*Networks) Teardown

func (b *Networks) Teardown() error

Teardown all clients

type NewEVMClientFn

type NewEVMClientFn func(
	networkName string,
	networkConfig map[string]interface{},
	urls []*url.URL,
) (EVMClient, error)

NewBlockchainClientFn external client implementation function networkName must match a key in "networks" in networks.yaml config networkConfig is just an arbitrary config you provide in "networks" for your key

type NodeBlock

type NodeBlock struct {
	NodeID int
	*types.Block
}

NodeBlock block with a node ID which mined it

type TXGasData

type TXGasData struct {
	TXHash            string
	Value             uint64
	GasLimit          uint64
	GasUsed           uint64
	GasPrice          uint64
	CumulativeGasUsed uint64
}

TXGasData transaction gas data

type TransactionConfirmer

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

TransactionConfirmer is an implementation of HeaderEventSubscription that checks whether tx are confirmed

func NewTransactionConfirmer

func NewTransactionConfirmer(client EVMClient, tx *types.Transaction, minConfirmations int) *TransactionConfirmer

NewTransactionConfirmer returns a new instance of the transaction confirmer that waits for on-chain minimum confirmations

func (*TransactionConfirmer) ReceiveBlock

func (t *TransactionConfirmer) ReceiveBlock(block NodeBlock) error

ReceiveBlock the implementation of the HeaderEventSubscription that receives each block and checks tx confirmation

func (*TransactionConfirmer) Wait

func (t *TransactionConfirmer) Wait() error

Wait is a blocking function that waits until the transaction is complete

Jump to

Keyboard shortcuts

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