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

Avoid panics #389

Merged
merged 19 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all 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
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 {
afkbyte marked this conversation as resolved.
Show resolved Hide resolved
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("ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80")
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(
afkbyte marked this conversation as resolved.
Show resolved Hide resolved
"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
Loading