diff --git a/inabox/deploy/config.go b/inabox/deploy/config.go index c73f4794d..01795d65f 100644 --- a/inabox/deploy/config.go +++ b/inabox/deploy/config.go @@ -146,8 +146,9 @@ func (env *Config) generateChurnerVars(ind int, graphUrl, logPath, grpcPort stri CHURNER_GRAPH_URL: graphUrl, CHURNER_INDEXER_PULL_INTERVAL: "1s", - CHURNER_ENABLE_METRICS: "true", - CHURNER_METRICS_HTTP_PORT: "9095", + CHURNER_ENABLE_METRICS: "true", + CHURNER_METRICS_HTTP_PORT: "9095", + CHURNER_CHURN_APPROVAL_INTERVAL: "900s", } env.applyDefaults(&v, "CHURNER", "churner", ind) diff --git a/inabox/deploy/env_vars.go b/inabox/deploy/env_vars.go index 6b73ebc6b..f701ce64d 100644 --- a/inabox/deploy/env_vars.go +++ b/inabox/deploy/env_vars.go @@ -424,6 +424,8 @@ type ChurnerVars struct { CHURNER_PER_PUBLIC_KEY_RATE_LIMIT string + CHURNER_CHURN_APPROVAL_INTERVAL string + CHURNER_METRICS_HTTP_PORT string CHURNER_CHAIN_RPC string diff --git a/operators/churner/churner.go b/operators/churner/churner.go index c83e39370..dd857fbba 100644 --- a/operators/churner/churner.go +++ b/operators/churner/churner.go @@ -20,8 +20,7 @@ import ( ) var ( - bipMultiplier = big.NewInt(10000) - secondsTillExpiry = 3600 * time.Second + bipMultiplier = big.NewInt(10000) ) type ChurnRequest struct { @@ -50,9 +49,10 @@ type churner struct { Transactor core.Transactor QuorumCount uint8 - privateKey *ecdsa.PrivateKey - logger logging.Logger - metrics *Metrics + privateKey *ecdsa.PrivateKey + logger logging.Logger + metrics *Metrics + churnApprovalInterval time.Duration } func NewChurner( @@ -67,14 +67,17 @@ func NewChurner( return nil, err } + logger.Info("Churner created with config", "ChurnApprovalInterval", config.ChurnApprovalInterval) + return &churner{ Indexer: indexer, Transactor: transactor, QuorumCount: 0, - privateKey: privateKey, - logger: logger.With("component", "Churner"), - metrics: metrics, + privateKey: privateKey, + logger: logger.With("component", "Churner"), + metrics: metrics, + churnApprovalInterval: config.ChurnApprovalInterval, }, nil } @@ -285,8 +288,8 @@ func (c *churner) sign(ctx context.Context, operatorToRegisterAddress gethcommon var salt [32]byte copy(salt[:], saltKeccak256) - // set expiry to 3600s in the future - expiry := big.NewInt(now.Add(secondsTillExpiry).Unix()) + // set expiry to ChurnApprovalInterval in the future + expiry := big.NewInt(now.Add(c.churnApprovalInterval).Unix()) // sign and return signature hashToSign, err := c.Transactor.CalculateOperatorChurnApprovalDigestHash(ctx, operatorToRegisterAddress, operatorToRegisterId, operatorsToChurn, salt, expiry) diff --git a/operators/churner/config.go b/operators/churner/config.go index ae7832c6d..d35a72121 100644 --- a/operators/churner/config.go +++ b/operators/churner/config.go @@ -20,6 +20,7 @@ type Config struct { EigenDAServiceManagerAddr string PerPublicKeyRateLimit time.Duration + ChurnApprovalInterval time.Duration } func NewConfig(ctx *cli.Context) (*Config, error) { @@ -34,6 +35,7 @@ func NewConfig(ctx *cli.Context) (*Config, error) { BLSOperatorStateRetrieverAddr: ctx.GlobalString(flags.BlsOperatorStateRetrieverFlag.Name), EigenDAServiceManagerAddr: ctx.GlobalString(flags.EigenDAServiceManagerFlag.Name), PerPublicKeyRateLimit: ctx.GlobalDuration(flags.PerPublicKeyRateLimit.Name), + ChurnApprovalInterval: ctx.GlobalDuration(flags.ChurnApprovalInterval.Name), MetricsConfig: MetricsConfig{ HTTPPort: ctx.GlobalString(flags.MetricsHTTPPort.Name), EnableMetrics: ctx.GlobalBool(flags.EnableMetrics.Name), diff --git a/operators/churner/flags/flags.go b/operators/churner/flags/flags.go index e3c8ac89d..906096c49 100644 --- a/operators/churner/flags/flags.go +++ b/operators/churner/flags/flags.go @@ -65,6 +65,13 @@ var ( Value: "9100", EnvVar: common.PrefixEnvVar(envPrefix, "METRICS_HTTP_PORT"), } + ChurnApprovalInterval = cli.DurationFlag{ + Name: common.PrefixFlag(FlagPrefix, "churn-approval-interval"), + Usage: "If this interval is N mins, the churner will only approve a new churn request N mins after the previous approval", + Required: false, + EnvVar: common.PrefixEnvVar(envPrefix, "CHURN_APPROVAL_INTERVAL"), + Value: 15 * time.Minute, + } ) var requiredFlags = []cli.Flag{ @@ -78,6 +85,7 @@ var requiredFlags = []cli.Flag{ var optionalFlags = []cli.Flag{ PerPublicKeyRateLimit, MetricsHTTPPort, + ChurnApprovalInterval, } // Flags contains the list of configuration options available to the binary. diff --git a/operators/churner/server_test.go b/operators/churner/server_test.go index 00fb2ad85..a6261b576 100644 --- a/operators/churner/server_test.go +++ b/operators/churner/server_test.go @@ -6,6 +6,7 @@ import ( "log" "math/big" "testing" + "time" "github.com/Layr-Labs/eigenda/common" "github.com/Layr-Labs/eigenda/common/geth" @@ -92,7 +93,7 @@ func TestChurn(t *testing.T) { // retry prior to expiry should fail _, err = s.Churn(ctx, request) assert.NotNil(t, err) - assert.Equal(t, err.Error(), "rpc error: code = ResourceExhausted desc = previous approval not expired, retry in 3600 seconds") + assert.Equal(t, err.Error(), "rpc error: code = ResourceExhausted desc = previous approval not expired, retry in 900 seconds") } func TestChurnWithInvalidQuorum(t *testing.T) { @@ -169,6 +170,7 @@ func newTestServer(t *testing.T) *churner.Server { PrivateKeyString: churnerPrivateKeyHex, NumRetries: numRetries, }, + ChurnApprovalInterval: 15 * time.Minute, } var err error diff --git a/operators/churner/tests/churner_test.go b/operators/churner/tests/churner_test.go index 0f5486b95..af013fe62 100644 --- a/operators/churner/tests/churner_test.go +++ b/operators/churner/tests/churner_test.go @@ -214,6 +214,7 @@ func newTestServer(t *testing.T) *churner.Server { LoggerConfig: common.DefaultLoggerConfig(), BLSOperatorStateRetrieverAddr: testConfig.EigenDA.OperatorStateRetreiver, EigenDAServiceManagerAddr: testConfig.EigenDA.ServiceManager, + ChurnApprovalInterval: 15 * time.Minute, } operatorTransactorChurner, err := createTransactorFromScratch(