Skip to content

Commit

Permalink
Avoid panics (#389)
Browse files Browse the repository at this point in the history
Co-authored-by: Tomás Grüner <[email protected]>
  • Loading branch information
pablodeymo and MegaRedHand authored Jan 17, 2025
1 parent 1eff90f commit 583fc32
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 197 deletions.
35 changes: 25 additions & 10 deletions chainio/clients/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package clients
import (
"context"
"crypto/ecdsa"
"fmt"
"time"

"github.com/ethereum/go-ethereum/ethclient"
Expand Down Expand Up @@ -56,7 +57,10 @@ func BuildReadClients(
config BuildAllConfig,
logger logging.Logger,
) (*ReadClients, error) {
config.validate(logger)
err := config.validate(logger)
if err != nil {
return nil, utils.WrapError("Failed to validate logger", err)
}

// Create the metrics server
promReg := prometheus.NewRegistry()
Expand Down Expand Up @@ -127,7 +131,10 @@ func BuildAll(
ecdsaPrivateKey *ecdsa.PrivateKey,
logger logging.Logger,
) (*Clients, error) {
config.validate(logger)
err := config.validate(logger)
if err != nil {
return nil, utils.WrapError("Failed to validate logger", err)
}

// Create the metrics server
promReg := prometheus.NewRegistry()
Expand All @@ -148,7 +155,8 @@ func BuildAll(
defer cancel()
chainid, err := ethHttpClient.ChainID(rpcCtx)
if err != nil {
logger.Fatal("Cannot get chain id", "err", err)
logger.Error("Cannot get chain id", "err", err)
return nil, utils.WrapError("Cannot get chain id", err)
}
signerV2, addr, err := signerv2.SignerFromConfig(signerv2.Config{PrivateKey: ecdsaPrivateKey}, chainid)
if err != nil {
Expand Down Expand Up @@ -215,23 +223,30 @@ func BuildAll(
// Very basic validation that makes sure all fields are nonempty
// we might eventually want more sophisticated validation, based on regexp,
// or use something like https://json-schema.org/ (?)
func (config *BuildAllConfig) validate(logger logging.Logger) {
func (config *BuildAllConfig) validate(logger logging.Logger) error {
if config.EthHttpUrl == "" {
logger.Fatalf("BuildAllConfig.validate: Missing eth http url")
logger.Error("BuildAllConfig.validate: Missing eth http url")
return fmt.Errorf("BuildAllConfig.validate: Missing eth http url")
}
if config.EthWsUrl == "" {
logger.Fatalf("BuildAllConfig.validate: Missing eth ws url")
logger.Error("BuildAllConfig.validate: Missing eth ws url")
return fmt.Errorf("BuildAllConfig.validate: Missing eth ws url")
}
if config.RegistryCoordinatorAddr == "" {
logger.Fatalf("BuildAllConfig.validate: Missing bls registry coordinator address")
logger.Error("BuildAllConfig.validate: Missing bls registry coordinator address")
return fmt.Errorf("BuildAllConfig.validate: Missing bls registry coordinator address")
}
if config.OperatorStateRetrieverAddr == "" {
logger.Fatalf("BuildAllConfig.validate: Missing bls operator state retriever address")
logger.Error("BuildAllConfig.validate: Missing bls operator state retriever address")
return fmt.Errorf("BuildAllConfig.validate: Missing bls operator state retriever address")
}
if config.AvsName == "" {
logger.Fatalf("BuildAllConfig.validate: Missing avs name")
logger.Error("BuildAllConfig.validate: Missing avs name")
return fmt.Errorf("BuildAllConfig.validate: Missing avs name")
}
if config.PromMetricsIpPortAddress == "" {
logger.Fatalf("BuildAllConfig.validate: Missing prometheus metrics ip port address")
logger.Error("BuildAllConfig.validate: Missing prometheus metrics ip port address")
return fmt.Errorf("BuildAllConfig.validate: Missing prometheus metrics ip port address")
}
return nil
}
88 changes: 51 additions & 37 deletions chainio/txmgr/geometric/geometric_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/Layr-Labs/eigensdk-go/logging"
"github.com/Layr-Labs/eigensdk-go/signerv2"
"github.com/Layr-Labs/eigensdk-go/testutils"
"github.com/Layr-Labs/eigensdk-go/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
Expand All @@ -23,63 +24,76 @@ var (
chainid = big.NewInt(31337)
)

func createTx(client eth.HttpBackend, address common.Address) (*types.Transaction, error) {
zeroAddr := common.HexToAddress("0x0")
nonce, err := client.PendingNonceAt(context.TODO(), address)
if err != nil {
return nil, utils.WrapError("Failed to get PendingNonceAt", err)
}
return types.NewTx(&types.DynamicFeeTx{
To: &zeroAddr,
Nonce: nonce,
}), nil
}

func createTxMgr(rpcUrl string, ecdsaPrivateKey *ecdsa.PrivateKey) (eth.HttpBackend, *GeometricTxManager, error) {
logger := logging.NewTextSLogger(os.Stdout, &logging.SLoggerOptions{})
client, err := ethclient.Dial(rpcUrl)
if err != nil {
return nil, nil, err
}
signerV2, signerAddr, err := signerv2.SignerFromConfig(signerv2.Config{PrivateKey: ecdsaPrivateKey}, chainid)
if err != nil {
return nil, nil, err
}
wallet, err := wallet.NewPrivateKeyWallet(client, signerV2, signerAddr, logger)
if err != nil {
return nil, nil, err
}
reg := prometheus.NewRegistry()
metrics := NewMetrics(reg, "example", logger)
return client, NewGeometricTxnManager(client, wallet, logger, metrics, GeometricTxnManagerParams{}), nil
}

func ExampleGeometricTxManager() {
anvilC, err := testutils.StartAnvilContainer("")
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
anvilUrl, err := anvilC.Endpoint(context.TODO(), "http")
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

ecdsaPrivateKey, err := crypto.HexToECDSA(testutils.ANVIL_FIRST_PRIVATE_KEY)
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
pk := ecdsaPrivateKey.PublicKey
address := crypto.PubkeyToAddress(pk)

client, txmgr := createTxMgr(anvilUrl, ecdsaPrivateKey)

tx := createTx(client, address)
_, err = txmgr.Send(context.TODO(), tx, true)
client, txmgr, err := createTxMgr(anvilUrl, ecdsaPrivateKey)
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

// we just add this to make sure the example runs
fmt.Println("Tx sent")
// Output: Tx sent
}

func createTx(client eth.HttpBackend, address common.Address) *types.Transaction {
zeroAddr := common.HexToAddress("0x0")
nonce, err := client.PendingNonceAt(context.TODO(), address)
tx, err := createTx(client, address)
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
return types.NewTx(&types.DynamicFeeTx{
To: &zeroAddr,
Nonce: nonce,
})
}

func createTxMgr(rpcUrl string, ecdsaPrivateKey *ecdsa.PrivateKey) (eth.HttpBackend, *GeometricTxManager) {
logger := logging.NewTextSLogger(os.Stdout, &logging.SLoggerOptions{})
client, err := ethclient.Dial(rpcUrl)
if err != nil {
panic(err)
}
signerV2, signerAddr, err := signerv2.SignerFromConfig(signerv2.Config{PrivateKey: ecdsaPrivateKey}, chainid)
if err != nil {
panic(err)
}
wallet, err := wallet.NewPrivateKeyWallet(client, signerV2, signerAddr, logger)
_, err = txmgr.Send(context.TODO(), tx, true)
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
reg := prometheus.NewRegistry()
metrics := NewMetrics(reg, "example", logger)
return client, NewGeometricTxnManager(client, wallet, logger, metrics, GeometricTxnManagerParams{})

// we just add this to make sure the example runs
fmt.Println("Tx sent")
// Output: Tx sent
}
5 changes: 3 additions & 2 deletions logging/zap_logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package logging
import (
"fmt"

"github.com/Layr-Labs/eigensdk-go/utils"
"go.uber.org/zap"
)

Expand All @@ -28,7 +29,7 @@ func NewZapLogger(env LogLevel) (Logger, error) {
} else if env == Development {
config = zap.NewDevelopmentConfig()
} else {
panic(fmt.Sprintf("Unknown environment. Expected %s or %s. Received %s.", Development, Production, env))
return nil, fmt.Errorf("unknown environment. Expected %s or %s. Received %s", Development, Production, env)
}

return NewZapLoggerByConfig(config, zap.AddCallerSkip(1))
Expand All @@ -39,7 +40,7 @@ func NewZapLogger(env LogLevel) (Logger, error) {
func NewZapLoggerByConfig(config zap.Config, options ...zap.Option) (Logger, error) {
logger, err := config.Build(options...)
if err != nil {
panic(err)
return nil, utils.WrapError("Can not build config with the given options", err)
}

return &ZapLogger{
Expand Down
14 changes: 10 additions & 4 deletions metrics/eigenmetrics_example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ package metrics_test

import (
"context"
"fmt"
"os"

"github.com/Layr-Labs/eigensdk-go/chainio/clients"
"github.com/Layr-Labs/eigensdk-go/chainio/clients/eth"
Expand All @@ -26,13 +28,15 @@ func ExampleEigenMetrics() {

logger, err := logging.NewZapLogger("development")
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

// get the Writer for the EL contracts
ecdsaPrivateKey, err := crypto.HexToECDSA("0x0")
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
operatorEcdsaAddr := crypto.PubkeyToAddress(ecdsaPrivateKey.PublicKey)

Expand All @@ -46,7 +50,8 @@ func ExampleEigenMetrics() {
}
clients, err := clients.BuildAll(chainioConfig, ecdsaPrivateKey, logger)
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
reg := prometheus.NewRegistry()
eigenMetrics := metrics.NewEigenMetrics("exampleAvs", ":9090", reg, logger)
Expand All @@ -71,7 +76,8 @@ func ExampleEigenMetrics() {
rpcCallsCollector := rpccalls.NewCollector("exampleAvs", reg)
instrumentedEthClient, err := eth.NewInstrumentedClient("http://localhost:8545", rpcCallsCollector)
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

eigenMetrics.Start(context.Background(), reg)
Expand Down
6 changes: 5 additions & 1 deletion nodeapi/nodeapi_example_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package nodeapi_test

import (
"fmt"
"os"

"github.com/Layr-Labs/eigensdk-go/logging"
"github.com/Layr-Labs/eigensdk-go/nodeapi"
)

func ExampleNodeApi() {
logger, err := logging.NewZapLogger("development")
if err != nil {
panic(err)
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}

nodeApi := nodeapi.NewNodeApi("testAvs", "v0.0.1", "localhost:8080", logger)
Expand Down
13 changes: 11 additions & 2 deletions services/avsregistry/avsregistry_chaincaller.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,20 @@ func (ar *AvsRegistryServiceChainCaller) GetOperatorsAvsStateAtBlock(
}
numquorums := len(quorumNumbers)
if len(operatorsStakesInQuorums) != numquorums {
ar.logger.Fatal(
ar.logger.Error(
"Number of quorums returned from GetOperatorsStakeInQuorumsAtBlock does not match number of quorums requested. Probably pointing to old contract or wrong implementation.",
"service",
"AvsRegistryServiceChainCaller",
"operatorsStakesInQuorums",
operatorsStakesInQuorums,
"numquorums",
numquorums,
)
return nil,
utils.WrapError(
"number of quorums returned from GetOperatorsStakeInQuorumsAtBlock does not match number of quorums requested. Probably pointing to old contract or wrong implementation",
nil,
)
}

for quorumIdx, quorumNum := range quorumNumbers {
Expand Down Expand Up @@ -149,7 +158,7 @@ func (ar *AvsRegistryServiceChainCaller) getOperatorInfo(
info, ok := ar.operatorInfoService.GetOperatorInfo(ctx, operatorAddr)
if !ok {
return types.OperatorInfo{}, fmt.Errorf(
"Failed to get operator info from operatorInfoService (operatorAddr: %v, operatorId: %v)",
"failed to get operator info from operatorInfoService (operatorAddr: %v, operatorId: %v)",
operatorAddr,
operatorId,
)
Expand Down
Loading

0 comments on commit 583fc32

Please sign in to comment.