diff --git a/chainio/clients/avsregistry/writer.go b/chainio/clients/avsregistry/writer.go index e3501bc4..2b9b9b4e 100644 --- a/chainio/clients/avsregistry/writer.go +++ b/chainio/clients/avsregistry/writer.go @@ -24,10 +24,11 @@ import ( ) type AvsRegistryWriter interface { - // TODO(samlaf): an operator that is already registered in a quorum can register with another quorum without passing signatures - // perhaps we should add another sdk function for this purpose, that just takes in a quorumNumber and socket? - // RegisterOperatorInQuorumWithAVSRegistryCoordinator is used to register a single operator with the AVS's registry coordinator. - // - operatorEcdsaPrivateKey is the operator's ecdsa private key (used to sign a message to register operator in eigenlayer's delegation manager) + // TODO(samlaf): an operator that is already registered in a quorum can register with another quorum without passing + // signatures perhaps we should add another sdk function for this purpose, that just takes in a quorumNumber and + // socket? RegisterOperatorInQuorumWithAVSRegistryCoordinator is used to register a single operator with the AVS's + // registry coordinator. - operatorEcdsaPrivateKey is the operator's ecdsa private key (used to sign a message to + // register operator in eigenlayer's delegation manager) // - operatorToAvsRegistrationSigSalt is a random salt used to prevent replay attacks // - operatorToAvsRegistrationSigExpiry is the expiry time of the signature RegisterOperatorInQuorumWithAVSRegistryCoordinator( @@ -42,7 +43,8 @@ type AvsRegistryWriter interface { // UpdateStakesOfEntireOperatorSetForQuorums is used by avs teams running https://github.com/Layr-Labs/avs-sync // to updates the stake of their entire operator set. - // Because of high gas costs of this operation, it typically needs to be called for every quorum, or perhaps for a small grouping of quorums + // Because of high gas costs of this operation, it typically needs to be called for every quorum, or perhaps for a + // small grouping of quorums // (highly dependent on number of operators per quorum) UpdateStakesOfEntireOperatorSetForQuorums( ctx context.Context, @@ -50,8 +52,9 @@ type AvsRegistryWriter interface { quorumNumbers []byte, ) (*gethtypes.Receipt, error) - // UpdateStakesOfOperatorSubsetForAllQuorums is meant to be used by single operators (or teams of operators, possibly running https://github.com/Layr-Labs/avs-sync) - // to update the stake of their own operator(s). This might be needed in the case that they received a lot of new stake delegations, and want this to be reflected + // UpdateStakesOfOperatorSubsetForAllQuorums is meant to be used by single operators (or teams of operators, + // possibly running https://github.com/Layr-Labs/avs-sync) to update the stake of their own operator(s). This might + // be needed in the case that they received a lot of new stake delegations, and want this to be reflected // in the AVS's registry coordinator. UpdateStakesOfOperatorSubsetForAllQuorums( ctx context.Context, @@ -165,10 +168,13 @@ func BuildAvsRegistryChainWriter( // TODO(samlaf): clean up this function func (w *AvsRegistryChainWriter) RegisterOperatorInQuorumWithAVSRegistryCoordinator( ctx context.Context, - // we need to pass the private key explicitly and can't use the signer because registering requires signing a message which isn't a transaction + // we need to pass the private key explicitly and can't use the signer because registering requires signing a + // message which isn't a transaction // and the signer can only signs transactions - // see operatorSignature in https://github.com/Layr-Labs/eigenlayer-middleware/blob/m2-mainnet/docs/RegistryCoordinator.md#registeroperator - // TODO(madhur): check to see if we can make the signer and txmgr more flexible so we can use them (and remote signers) to sign non txs + // see operatorSignature in + // https://github.com/Layr-Labs/eigenlayer-middleware/blob/m2-mainnet/docs/RegistryCoordinator.md#registeroperator + // TODO(madhur): check to see if we can make the signer and txmgr more flexible so we can use them (and remote + // signers) to sign non txs operatorEcdsaPrivateKey *ecdsa.PrivateKey, operatorToAvsRegistrationSigSalt [32]byte, operatorToAvsRegistrationSigExpiry *big.Int, @@ -196,7 +202,12 @@ func (w *AvsRegistryChainWriter) RegisterOperatorInQuorumWithAVSRegistryCoordina // params to register operator in delegation manager's operator-avs mapping msgToSign, err := w.elReader.CalculateDelegationApprovalDigestHash( - &bind.CallOpts{}, operatorAddr, w.serviceManagerAddr, operatorToAvsRegistrationSigSalt, operatorToAvsRegistrationSigExpiry) + &bind.CallOpts{}, + operatorAddr, + w.serviceManagerAddr, + operatorToAvsRegistrationSigSalt, + operatorToAvsRegistrationSigExpiry, + ) if err != nil { return nil, err } diff --git a/chainio/clients/builder.go b/chainio/clients/builder.go index fabe5e65..b4149682 100644 --- a/chainio/clients/builder.go +++ b/chainio/clients/builder.go @@ -40,7 +40,12 @@ type Clients struct { PrometheusRegistry *prometheus.Registry // Used if avs teams need to register avs-specific metrics } -func BuildAll(config BuildAllConfig, signerAddr gethcommon.Address, signerFn signerv2.SignerFn, logger logging.Logger) (*Clients, error) { +func BuildAll( + config BuildAllConfig, + signerAddr gethcommon.Address, + signerFn signerv2.SignerFn, + logger logging.Logger, +) (*Clients, error) { config.validate(logger) // Create the metrics server diff --git a/logging/slog_logger.go b/logging/slog_logger.go new file mode 100644 index 00000000..ea0ad147 --- /dev/null +++ b/logging/slog_logger.go @@ -0,0 +1,75 @@ +package logging + +import ( + "fmt" + "log/slog" + "os" +) + +type SLogger struct { + logger *slog.Logger +} + +var _ Logger = (*SLogger)(nil) + +func NewSlogLogger(env LogLevel) Logger { + if env == Production { + logHandler := slog.NewJSONHandler(os.Stdout, nil).WithAttrs([]slog.Attr{slog.String("env", string(env))}) + logger := slog.New(logHandler) + return &SLogger{ + logger: logger, + } + } else if env == Development { + // Even though code is same for both environments, we are keeping it separate to show that we can have different + // implementations for different environments. For example, we can have log levels set differently + logHandler := slog.NewJSONHandler(os.Stdout, nil).WithAttrs([]slog.Attr{slog.String("env", string(env))}) + logger := slog.New(logHandler) + return &SLogger{ + logger: logger, + } + } else { + panic(fmt.Sprintf("Unknown environment. Expected %s or %s. Received %s.", Development, Production, env)) + } +} + +func (s SLogger) Debug(msg string, tags ...any) { + s.logger.Debug(msg, tags...) +} + +func (s SLogger) Info(msg string, tags ...any) { + s.logger.Info(msg, tags...) +} + +func (s SLogger) Warn(msg string, tags ...any) { + s.logger.Warn(msg, tags...) +} + +func (s SLogger) Error(msg string, tags ...any) { + s.logger.Error(msg, tags...) +} + +func (s SLogger) Fatal(msg string, tags ...any) { + s.logger.Error(msg, tags...) + os.Exit(1) +} + +func (s SLogger) Debugf(template string, args ...interface{}) { + s.logger.Debug(fmt.Sprintf(template, args...)) +} + +func (s SLogger) Infof(template string, args ...interface{}) { + s.logger.Info(fmt.Sprintf(template, args...)) +} + +func (s SLogger) Warnf(template string, args ...interface{}) { + s.logger.Warn(fmt.Sprintf(template, args...)) +} + +func (s SLogger) Errorf(template string, args ...interface{}) { + s.logger.Error(fmt.Sprintf(template, args...)) +} + +func (s SLogger) Fatalf(template string, args ...interface{}) { + s.logger.Error(fmt.Sprintf(template, args...)) + os.Exit(1) +} diff --git a/logging/zap_logger.go b/logging/zap_logger.go index 5665e7af..22573e0f 100644 --- a/logging/zap_logger.go +++ b/logging/zap_logger.go @@ -61,26 +61,6 @@ func (z *ZapLogger) Fatal(msg string, tags ...any) { z.logger.Sugar().Fatalw(msg, tags...) } -func (z *ZapLogger) Debugm(msg string, tags map[string]any) { - z.logger.Debug(msg, convertTagsToZapFields(tags)...) -} - -func (z *ZapLogger) Infom(msg string, tags map[string]any) { - z.logger.Info(msg, convertTagsToZapFields(tags)...) -} - -func (z *ZapLogger) Warnm(msg string, tags map[string]any) { - z.logger.Warn(msg, convertTagsToZapFields(tags)...) -} - -func (z *ZapLogger) Errorm(msg string, tags map[string]any) { - z.logger.Error(msg, convertTagsToZapFields(tags)...) -} - -func (z *ZapLogger) Fatalm(msg string, tags map[string]any) { - z.logger.Fatal(msg, convertTagsToZapFields(tags)...) -} - func (z *ZapLogger) Debugf(template string, args ...interface{}) { z.logger.Sugar().Debugf(template, args...) } @@ -100,11 +80,3 @@ func (z *ZapLogger) Errorf(template string, args ...interface{}) { func (z *ZapLogger) Fatalf(template string, args ...interface{}) { z.logger.Sugar().Fatalf(template, args...) } - -func convertTagsToZapFields(tags map[string]any) []zap.Field { - zapFields := make([]zap.Field, 0) - for k, v := range tags { - zapFields = append(zapFields, zap.Any(k, v)) - } - return zapFields -} diff --git a/types/errors.go b/types/errors.go index ec737601..35d1a8ce 100644 --- a/types/errors.go +++ b/types/errors.go @@ -20,7 +20,9 @@ var ( ErrInvalidUrl = errors.New("invalid url") ErrInvalidImageMimeType = errors.New("invalid image mime-type. only png is supported") - ErrInvalidImageExtension = errors.New("invalid image extension. only " + strings.Join(ImageExtensions, ",") + "is supported") + ErrInvalidImageExtension = errors.New( + "invalid image extension. only " + strings.Join(ImageExtensions, ",") + "is supported", + ) // Metadata Errors ErrNameRequired = errors.New("name is required")