Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add read only builder #326

Merged
merged 8 commits into from
Aug 16, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 55 additions & 0 deletions chainio/clients/avsregistry/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,61 @@ import (
"github.com/Layr-Labs/eigensdk-go/logging"
)

// Build an AVS registry client with the given configuration,
// HTTP and WS clients, and logger, but without a private key.
//
// This is useful for read-only operations, such as fetching metrics.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does it mean by fetching metrics here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think can be confusing. I'll remove that bit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

func BuildClientsForEcMetrics(
samlaf marked this conversation as resolved.
Show resolved Hide resolved
config Config,
client eth.HttpBackend,
wsClient eth.WsBackend,
logger logging.Logger,
) (*ChainReader, *ChainSubscriber, *ContractBindings, error) {
avsBindings, err := NewBindingsFromConfig(
config,
client,
logger,
)

if err != nil {
return nil, nil, nil, nil, err
}

chainReader := NewChainReader(
avsBindings.RegistryCoordinatorAddr,
avsBindings.BlsApkRegistryAddr,
avsBindings.RegistryCoordinator,
avsBindings.OperatorStateRetriever,
avsBindings.StakeRegistry,
logger,
client,
)

chainSubscriber, err := NewSubscriberFromConfig(
config,
wsClient,
logger,
)
if err != nil {
return nil, nil, nil, err
}

// This is ugly, but we need elReader to be able to create the AVS writer
elChainReader, err := elcontracts.NewReaderFromConfig(
elcontracts.Config{
DelegationManagerAddress: avsBindings.DelegationManagerAddr,
AvsDirectoryAddress: avsBindings.AvsDirectoryAddr,
},
client,
logger,
)
if err != nil {
return nil, nil, nil, err
}

return chainReader, chainSubscriber, avsBindings, nil
}

func BuildClients(
config Config,
client eth.HttpBackend,
Expand Down
105 changes: 98 additions & 7 deletions chainio/clients/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,100 @@ type Clients struct {
PrometheusRegistry *prometheus.Registry // Used if avs teams need to register avs-specific metrics
}

func BuildAll(
// This is a struct that holds all the params that are needed to interact
// with the AVS and EL contracts without the Wallet/Private key.
// This is useful for read-only operations, such as fetching metrics.
type ClientsBase struct {
juanbono marked this conversation as resolved.
Show resolved Hide resolved
AvsRegistryChainReader *avsregistry.ChainReader
AvsRegistryChainSubscriber *avsregistry.ChainSubscriber
AvsRegistryChainWriter *avsregistry.ChainWriter
samlaf marked this conversation as resolved.
Show resolved Hide resolved
ElChainReader *elcontracts.ChainReader
EthHttpClient eth.HttpBackend
EthWsClient eth.WsBackend
AvsRegistryContractBindings *avsregistry.ContractBindings
EigenlayerContractBindings *elcontracts.ContractBindings
Metrics *metrics.EigenMetrics // exposes main avs node spec metrics that need to be incremented by avs code and used to start the metrics server
PrometheusRegistry *prometheus.Registry
}

// This is a struct that extends ClientsBase with Wallet and TxManager.
// This is useful for the full set of operations (reads and writes), such as sending transactions.
type ClientsWithPkKey struct {
samlaf marked this conversation as resolved.
Show resolved Hide resolved
ClientsBase
Wallet wallet.Wallet
TxManager txmgr.TxManager
ElChainWriter *elcontracts.ChainWriter
}

// Creates a ClientsBase struct with the given configuration and logger.
func BuildForEcMetrics(
config BuildAllConfig,
logger logging.Logger,
) (*ClientsBase, error) {
config.validate(logger)

// Create the metrics server
promReg := prometheus.NewRegistry()
eigenMetrics := metrics.NewEigenMetrics(config.AvsName, config.PromMetricsIpPortAddress, promReg, logger)

// creating two types of Eth clients: HTTP and WS
ethHttpClient, err := ethclient.Dial(config.EthHttpUrl)
if err != nil {
return nil, utils.WrapError("Failed to create Eth Http client", err)
}

ethWsClient, err := ethclient.Dial(config.EthWsUrl)
if err != nil {
return nil, utils.WrapError("Failed to create Eth WS client", err)
}

// creating AVS clients: Reader
avsRegistryChainReader, avsRegistryChainSubscriber, avsRegistryContractBindings, err := avsregistry.BuildClientsForEcMetrics(
avsregistry.Config{
RegistryCoordinatorAddress: gethcommon.HexToAddress(config.RegistryCoordinatorAddr),
OperatorStateRetrieverAddress: gethcommon.HexToAddress(config.OperatorStateRetrieverAddr),
},
ethHttpClient,
ethWsClient,
logger,
)
if err != nil {
return nil, utils.WrapError("Failed to create AVS Registry Reader and Writer", err)
}

// creating EL clients: Reader and EigenLayer Contract Bindings
elChainReader, elContractBindings, err := elcontracts.BuildClientsForEcMetrics(
elcontracts.Config{
DelegationManagerAddress: avsRegistryContractBindings.DelegationManagerAddr,
AvsDirectoryAddress: avsRegistryContractBindings.AvsDirectoryAddr,
},
ethHttpClient,
logger,
eigenMetrics,
)
if err != nil {
return nil, utils.WrapError("Failed to create EL Reader and Writer", err)
}

base := ClientsBase{
ElChainReader: elChainReader,
AvsRegistryChainReader: avsRegistryChainReader,
AvsRegistryChainSubscriber: avsRegistryChainSubscriber,
EthHttpClient: ethHttpClient,
EthWsClient: ethWsClient,
EigenlayerContractBindings: elContractBindings,
AvsRegistryContractBindings: avsRegistryContractBindings,
Metrics: eigenMetrics,
PrometheusRegistry: promReg,
}
return &base, nil
}

func BuildAll( // BUILDS A ClientsWithPkKey
config BuildAllConfig,
ecdsaPrivateKey *ecdsa.PrivateKey,
logger logging.Logger,
) (*Clients, error) {
) (*ClientsWithPkKey, error) {
samlaf marked this conversation as resolved.
Show resolved Hide resolved
config.validate(logger)

// Create the metrics server
Expand Down Expand Up @@ -120,22 +209,24 @@ func BuildAll(
return nil, utils.WrapError("Failed to create EL Reader and Writer", err)
}

return &Clients{
base := ClientsBase{
ElChainReader: elChainReader,
ElChainWriter: elChainWriter,
AvsRegistryChainReader: avsRegistryChainReader,
AvsRegistryChainSubscriber: avsRegistryChainSubscriber,
AvsRegistryChainWriter: avsRegistryChainWriter,
EthHttpClient: ethHttpClient,
EthWsClient: ethWsClient,
Wallet: pkWallet,
TxManager: txMgr,
EigenlayerContractBindings: elContractBindings,
AvsRegistryContractBindings: avsRegistryContractBindings,
Metrics: eigenMetrics,
PrometheusRegistry: promReg,
}
return &ClientsWithPkKey{
ClientsBase: base,
ElChainWriter: elChainWriter,
Wallet: pkWallet,
TxManager: txMgr,
}, nil

}

// Very basic validation that makes sure all fields are nonempty
Expand Down
30 changes: 30 additions & 0 deletions chainio/clients/elcontracts/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,36 @@ import (
"github.com/Layr-Labs/eigensdk-go/metrics"
)

// Creates a ClientsBase struct (for read operations) with the given:
// configuration, HTTP client, logger and metrics.
func BuildClientsForEcMetrics(
samlaf marked this conversation as resolved.
Show resolved Hide resolved
config Config,
client eth.HttpBackend,
logger logging.Logger,
eigenMetrics *metrics.EigenMetrics,
) (*ChainReader, *ContractBindings, error) {
elContractBindings, err := NewBindingsFromConfig(
config,
client,
logger,
)
if err != nil {
return nil, nil, err
}

elChainReader := NewChainReader(
elContractBindings.Slasher,
elContractBindings.DelegationManager,
elContractBindings.StrategyManager,
elContractBindings.AvsDirectory,
elContractBindings.RewardsCoordinator,
logger,
client,
)

return elChainReader, elContractBindings, nil
}

func BuildClients(
config Config,
client eth.HttpBackend,
Expand Down