Skip to content

Commit 4f2daf2

Browse files
committed
progress
1 parent c99d3a3 commit 4f2daf2

File tree

4 files changed

+92
-29
lines changed

4 files changed

+92
-29
lines changed

core/chainio/avs_writer.go

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,16 @@ func (w *AvsWriter) SendAggregatedResponse(batchIdentifierHash [32]byte, batchMe
9595
txOpts.NoSend = false
9696
i := 0
9797

98+
// Set Retry condfig for RespondToTaskV2
99+
respondToTaskV2Config := retry.DefaultRetryConfig()
100+
respondToTaskV2Config.NumRetries = 0
101+
respondToTaskV2Config.MaxElapsedTime = 0
102+
103+
// Set Retry config for WaitForTxRetryable
104+
waitForTxConfig := retry.DefaultRetryConfig()
105+
waitForTxConfig.MaxInterval = 2 * time.Second
106+
waitForTxConfig.NumRetries = 0
107+
98108
respondToTaskV2Func := func() (*types.Receipt, error) {
99109
gasPrice, err := utils.GetGasPriceRetryable(w.Client, w.ClientFallback)
100110
if err != nil {
@@ -126,7 +136,8 @@ func (w *AvsWriter) SendAggregatedResponse(batchIdentifierHash [32]byte, batchMe
126136
return nil, err
127137
}
128138

129-
receipt, err := utils.WaitForTransactionReceiptRetryable(w.Client, w.ClientFallback, tx.Hash(), timeToWaitBeforeBump)
139+
waitForTxConfig.MaxElapsedTime = timeToWaitBeforeBump
140+
receipt, err := utils.WaitForTransactionReceiptRetryable(w.Client, w.ClientFallback, tx.Hash(), waitForTxConfig)
130141
if receipt != nil {
131142
return receipt, nil
132143
}
@@ -142,7 +153,8 @@ func (w *AvsWriter) SendAggregatedResponse(batchIdentifierHash [32]byte, batchMe
142153
return nil, fmt.Errorf("transaction failed")
143154
}
144155

145-
return retry.RetryWithData(respondToTaskV2Func, retry.MinDelay, retry.RetryFactor, 0, retry.MaxInterval, 0)
156+
//return retry.RetryWithData(respondToTaskV2Func, retry.MinDelay, retry.RetryFactor, 0, retry.MaxInterval, 0)
157+
return retry.RetryWithData(respondToTaskV2Func, respondToTaskV2Config)
146158
}
147159

148160
func (w *AvsWriter) checkRespondToTaskFeeLimit(tx *types.Transaction, txOpts bind.TransactOpts, batchIdentifierHash [32]byte, senderAddress [20]byte) error {

core/retry.go

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,47 @@ func (e PermanentError) Is(err error) bool {
2525
}
2626

2727
const (
28-
MinDelay = 1 * time.Second // Initial delay for retry interval.
29-
MaxInterval = 60 * time.Second // Maximum interval an individual retry may have.
30-
MaxElapsedTime = 0 * time.Second // Maximum time all retries may take. `0` corresponds to no limit on the time of the retries.
31-
RetryFactor float64 = 2 // Multiplier factor computed exponential retry interval is scaled by.
32-
NumRetries uint64 = 3 // Total number of retries attempted.
33-
MinDelayChain = 12 * time.Second // Initial delay for retry interval for contract calls. Corresponds to 1 ethereum block.
34-
MaxIntervalChain = 2 * time.Minute // Maximum interval for an individual retry.
28+
DefaultInitialInterval = 1 * time.Second // Initial delay for retry interval.
29+
DefaultMaxInterval = 60 * time.Second // Maximum interval an individual retry may have.
30+
DefaultMaxElapsedTime = 0 * time.Second // Maximum time all retries may take. `0` corresponds to no limit on the time of the retries.
31+
DefaultRandomizationFactor float64 = 0 // Randomization (Jitter) factor used to map retry interval to a range of values around the computed interval. In precise terms (random value in range [1 - randomizationfactor, 1 + randomizationfactor]). NOTE: This is set to 0 as we do not use jitter in Aligned.
32+
DefaultMultiplier float64 = 2 // Multiplier factor computed exponential retry interval is scaled by.
33+
DefaultNumRetries uint64 = 3 // Total number of retries attempted.
34+
ChainInitialInterval = 12 * time.Second // Initial delay for retry interval for contract calls. Corresponds to 1 ethereum block.
35+
ChainMaxInterval = 2 * time.Minute // Maximum interval for an individual retry.
3536
)
3637

38+
type RetryConfig struct {
39+
InitialInterval time.Duration // Initial delay for retry interval.
40+
MaxInterval time.Duration // Maximum interval an individual retry may have.
41+
MaxElapsedTime time.Duration // Maximum time all retries may take. `0` corresponds to no limit on the time of the retries.
42+
RandomizationFactor float64
43+
Multiplier float64
44+
NumRetries uint64
45+
}
46+
47+
func DefaultRetryConfig() *RetryConfig {
48+
return &RetryConfig{
49+
InitialInterval: DefaultInitialInterval,
50+
MaxInterval: DefaultMaxInterval,
51+
MaxElapsedTime: DefaultMaxElapsedTime,
52+
RandomizationFactor: DefaultRandomizationFactor,
53+
Multiplier: DefaultMultiplier,
54+
NumRetries: DefaultNumRetries,
55+
}
56+
}
57+
58+
func ChainRetryConfig() *RetryConfig {
59+
return &RetryConfig{
60+
InitialInterval: ChainInitialInterval,
61+
MaxInterval: ChainMaxInterval,
62+
MaxElapsedTime: DefaultMaxElapsedTime,
63+
RandomizationFactor: DefaultRandomizationFactor,
64+
Multiplier: DefaultMultiplier,
65+
NumRetries: DefaultNumRetries,
66+
}
67+
}
68+
3769
/*
3870
Retry and RetryWithData are custom retry functions used in Aligned's aggregator and operator to facilitate consistent retry logic across the system.
3971
They are interfaces for around Cenk Alti (https://github.com/cenkalti) backoff library (https://github.com/cenkalti/backoff). We would like to thank him for his great work.
@@ -91,8 +123,10 @@ request retry_interval (12 sec) randomized_interval (0.5) randomized_int
91123
Reference: https://github.com/cenkalti/backoff/blob/v4/exponential.go#L9
92124
*/
93125

126+
// TODO: Make config optional by using default but passing nil.
94127
// Same as Retry only that the functionToRetry can return a value upon correct execution
95-
func RetryWithData[T any](functionToRetry func() (T, error), minDelay time.Duration, factor float64, maxTries uint64, maxInterval time.Duration, maxElapsedTime time.Duration) (T, error) {
128+
func RetryWithData[T any](functionToRetry func() (T, error), config *RetryConfig) (T, error) {
129+
//func RetryWithData[T any](functionToRetry func() (T, error), minDelay time.Duration, factor float64, maxTries uint64, maxInterval time.Duration, maxElapsedTime time.Duration) (T, error) {
96130
f := func() (T, error) {
97131
var (
98132
val T
@@ -120,15 +154,15 @@ func RetryWithData[T any](functionToRetry func() (T, error), minDelay time.Durat
120154

121155
randomOption := backoff.WithRandomizationFactor(0)
122156

123-
initialRetryOption := backoff.WithInitialInterval(minDelay)
124-
multiplierOption := backoff.WithMultiplier(factor)
125-
maxIntervalOption := backoff.WithMaxInterval(maxInterval)
126-
maxElapsedTimeOption := backoff.WithMaxElapsedTime(maxElapsedTime)
157+
initialRetryOption := backoff.WithInitialInterval(config.InitialInterval)
158+
multiplierOption := backoff.WithMultiplier(config.Multiplier)
159+
maxIntervalOption := backoff.WithMaxInterval(config.MaxInterval)
160+
maxElapsedTimeOption := backoff.WithMaxElapsedTime(config.MaxElapsedTime)
127161
expBackoff := backoff.NewExponentialBackOff(randomOption, multiplierOption, initialRetryOption, maxIntervalOption, maxElapsedTimeOption)
128162
var maxRetriesBackoff backoff.BackOff
129163

130-
if maxTries > 0 {
131-
maxRetriesBackoff = backoff.WithMaxRetries(expBackoff, maxTries)
164+
if config.NumRetries > 0 {
165+
maxRetriesBackoff = backoff.WithMaxRetries(expBackoff, config.NumRetries)
132166
} else {
133167
maxRetriesBackoff = expBackoff
134168
}
@@ -142,7 +176,7 @@ func RetryWithData[T any](functionToRetry func() (T, error), minDelay time.Durat
142176
// from the configuration are reached, or until a `PermanentError` is returned.
143177
// The function to be retried should return `PermanentError` when the condition for stop retrying
144178
// is met.
145-
func Retry(functionToRetry func() error, minDelay time.Duration, factor float64, maxTries uint64, maxInterval time.Duration, maxElapsedTime time.Duration) error {
179+
func Retry(functionToRetry func() error, config *RetryConfig) error {
146180
f := func() error {
147181
var err error
148182
func() {
@@ -167,15 +201,15 @@ func Retry(functionToRetry func() error, minDelay time.Duration, factor float64,
167201

168202
randomOption := backoff.WithRandomizationFactor(0)
169203

170-
initialRetryOption := backoff.WithInitialInterval(minDelay)
171-
multiplierOption := backoff.WithMultiplier(factor)
172-
maxIntervalOption := backoff.WithMaxInterval(maxInterval)
173-
maxElapsedTimeOption := backoff.WithMaxElapsedTime(maxElapsedTime)
204+
initialRetryOption := backoff.WithInitialInterval(config.InitialInterval)
205+
multiplierOption := backoff.WithMultiplier(config.Multiplier)
206+
maxIntervalOption := backoff.WithMaxInterval(config.MaxInterval)
207+
maxElapsedTimeOption := backoff.WithMaxElapsedTime(config.MaxElapsedTime)
174208
expBackoff := backoff.NewExponentialBackOff(randomOption, multiplierOption, initialRetryOption, maxIntervalOption, maxElapsedTimeOption)
175209
var maxRetriesBackoff backoff.BackOff
176210

177-
if maxTries > 0 {
178-
maxRetriesBackoff = backoff.WithMaxRetries(expBackoff, maxTries)
211+
if config.NumRetries > 0 {
212+
maxRetriesBackoff = backoff.WithMaxRetries(expBackoff, config.NumRetries)
179213
} else {
180214
maxRetriesBackoff = expBackoff
181215
}

core/retry_test.go

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,16 @@ func TestRetryWithData(t *testing.T) {
4242
x, err := DummyFunction(43)
4343
return &x, err
4444
}
45-
_, err := retry.RetryWithData(function, 1000, 2, 3, retry.MaxInterval, retry.MaxElapsedTime)
45+
46+
config := &retry.RetryConfig{
47+
InitialInterval: 1000,
48+
MaxInterval: 2,
49+
MaxElapsedTime: 3,
50+
RandomizationFactor: 0,
51+
Multiplier: retry.DefaultMultiplier,
52+
NumRetries: retry.DefaultNumRetries,
53+
}
54+
_, err := retry.RetryWithData(function, config)
4655
if err != nil {
4756
t.Errorf("Retry error!: %s", err)
4857
}
@@ -53,7 +62,15 @@ func TestRetry(t *testing.T) {
5362
_, err := DummyFunction(43)
5463
return err
5564
}
56-
err := retry.Retry(function, 1000, 2, 3, retry.MaxInterval, retry.MaxElapsedTime)
65+
config := &retry.RetryConfig{
66+
InitialInterval: 1000,
67+
MaxInterval: 2,
68+
MaxElapsedTime: 3,
69+
RandomizationFactor: 0,
70+
Multiplier: retry.DefaultMultiplier,
71+
NumRetries: retry.DefaultNumRetries,
72+
}
73+
err := retry.Retry(function, config)
5774
if err != nil {
5875
t.Errorf("Retry error!: %s", err)
5976
}

core/utils/eth_client_utils.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package utils
33
import (
44
"context"
55
"math/big"
6-
"time"
76

87
"github.com/Layr-Labs/eigensdk-go/chainio/clients/eth"
98
eigentypes "github.com/Layr-Labs/eigensdk-go/types"
@@ -20,7 +19,7 @@ import (
2019
// Setting a higher value will imply doing less retries across the waitTimeout, and so we might lose the receipt
2120
// All errors are considered Transient Errors
2221
// - Retry times: 0.5s, 1s, 2s, 2s, 2s, ... until it reaches waitTimeout
23-
func WaitForTransactionReceiptRetryable(client eth.InstrumentedClient, fallbackClient eth.InstrumentedClient, txHash gethcommon.Hash, waitTimeout time.Duration) (*types.Receipt, error) {
22+
func WaitForTransactionReceiptRetryable(client eth.InstrumentedClient, fallbackClient eth.InstrumentedClient, txHash gethcommon.Hash, config *retry.RetryConfig) (*types.Receipt, error) {
2423
receipt_func := func() (*types.Receipt, error) {
2524
receipt, err := client.TransactionReceipt(context.Background(), txHash)
2625
if err != nil {
@@ -32,7 +31,7 @@ func WaitForTransactionReceiptRetryable(client eth.InstrumentedClient, fallbackC
3231
}
3332
return receipt, nil
3433
}
35-
return retry.RetryWithData(receipt_func, retry.MinDelay, retry.RetryFactor, 0, time.Second*2, waitTimeout)
34+
return retry.RetryWithData(receipt_func, config)
3635
}
3736

3837
func BytesToQuorumNumbers(quorumNumbersBytes []byte) eigentypes.QuorumNums {
@@ -71,6 +70,7 @@ func CalculateGasPriceBumpBasedOnRetry(currentGasPrice *big.Int, baseBumpPercent
7170
return bumpedGasPrice
7271
}
7372

73+
//TODO: move to retryable function file
7474
/*
7575
GetGasPriceRetryable
7676
Get the gas price from the client with retry logic.
@@ -89,5 +89,5 @@ func GetGasPriceRetryable(client eth.InstrumentedClient, fallbackClient eth.Inst
8989

9090
return gasPrice, nil
9191
}
92-
return retry.RetryWithData(respondToTaskV2_func, retry.MinDelay, retry.RetryFactor, retry.NumRetries, retry.MaxInterval, retry.MaxElapsedTime)
92+
return retry.RetryWithData(respondToTaskV2_func, retry.DefaultRetryConfig())
9393
}

0 commit comments

Comments
 (0)