Skip to content

Commit

Permalink
calculate retry config for conditionals
Browse files Browse the repository at this point in the history
  • Loading branch information
infiloop2 committed Feb 20, 2024
1 parent cc46df7 commit 783ed9c
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net/http"
"time"

automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types"
"github.com/smartcontractkit/chainlink-common/pkg/types"

"github.com/ethereum/go-ethereum/accounts/abi"
Expand Down Expand Up @@ -46,8 +47,7 @@ var GenerateHMACFn = func(method string, path string, body []byte, clientId stri
}

// CalculateRetryConfig returns plugin retry interval based on how many times plugin has retried this work
// TODO: Return false for conditionals on first retry
var CalculateRetryConfigFn = func(prk string, mercuryConfig MercuryConfigProvider) (retryInterval time.Duration) {
var CalculateRetryConfigFn = func(upkeepType automationTypes.UpkeepType, prk string, mercuryConfig MercuryConfigProvider) (retryInterval time.Duration) {
var retries int
totalAttempts, ok := mercuryConfig.GetPluginRetry(prk)
if ok {
Expand All @@ -62,6 +62,10 @@ var CalculateRetryConfigFn = func(prk string, mercuryConfig MercuryConfigProvide
} else {
retryInterval = 1 * time.Second
}
if upkeepType == automationTypes.ConditionTrigger {
// Conditional Upkees don't have any pipeline retries as they automatically get checked on a new block
retryInterval = RetryIntervalTimeout
}
mercuryConfig.SetPluginRetry(prk, retries+1, cache.DefaultExpiration)
return retryInterval
}
Expand Down Expand Up @@ -95,7 +99,7 @@ type MercuryClient interface {
// retryable: whether the request is retryable. Only applicable for errored states.
// retryInterval: the interval to wait before retrying the request. Only applicable for errored states.
// err: non nil if some internal error occurs in pipeline
DoRequest(ctx context.Context, streamsLookup *StreamsLookup, pluginRetryKey string) (encoding.PipelineExecutionState, [][]byte, encoding.ErrCode, bool, time.Duration, error)
DoRequest(ctx context.Context, streamsLookup *StreamsLookup, upkeepType automationTypes.UpkeepType, pluginRetryKey string) (encoding.PipelineExecutionState, [][]byte, encoding.ErrCode, bool, time.Duration, error)
}

type StreamsLookupError struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import (
"github.com/stretchr/testify/assert"

"github.com/smartcontractkit/chainlink-common/pkg/types"

automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types"
"github.com/smartcontractkit/chainlink/v2/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/encoding"
)

Expand Down Expand Up @@ -282,7 +284,7 @@ func Test_CalculateRetryConfigFn(t *testing.T) {
cfg := newMercuryConfigMock()
var result time.Duration
for i := 0; i < tc.times; i++ {
result = CalculateRetryConfigFn("prk", cfg)
result = CalculateRetryConfigFn(automationTypes.ConditionTrigger, "prk", cfg)
}
assert.Equal(t, tc.expected, result)
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,11 +247,12 @@ func (s *streams) DoMercuryRequest(ctx context.Context, lookup *mercury.StreamsL
var state, values, errCode, retryable, retryInterval = encoding.NoPipelineError, [][]byte{}, encoding.ErrCodeNil, false, 0 * time.Second
var err error
pluginRetryKey := generatePluginRetryKey(checkResults[i].WorkID, lookup.Block)
upkeepType := core.GetUpkeepType(checkResults[i].UpkeepID)

if lookup.IsMercuryV02() {
state, values, errCode, retryable, retryInterval, err = s.v02Client.DoRequest(ctx, lookup, pluginRetryKey)
state, values, errCode, retryable, retryInterval, err = s.v02Client.DoRequest(ctx, lookup, upkeepType, pluginRetryKey)
} else if lookup.IsMercuryV03() {
state, values, errCode, retryable, retryInterval, err = s.v03Client.DoRequest(ctx, lookup, pluginRetryKey)
state, values, errCode, retryable, retryInterval, err = s.v03Client.DoRequest(ctx, lookup, upkeepType, pluginRetryKey)
}

if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (

"github.com/avast/retry-go/v4"
"github.com/ethereum/go-ethereum/common/hexutil"
automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types"

"github.com/smartcontractkit/chainlink-common/pkg/services"

Expand Down Expand Up @@ -53,7 +54,7 @@ func NewClient(mercuryConfig mercury.MercuryConfigProvider, httpClient mercury.H
}
}

func (c *client) DoRequest(ctx context.Context, streamsLookup *mercury.StreamsLookup, pluginRetryKey string) (encoding.PipelineExecutionState, [][]byte, encoding.ErrCode, bool, time.Duration, error) {
func (c *client) DoRequest(ctx context.Context, streamsLookup *mercury.StreamsLookup, upkeepType automationTypes.UpkeepType, pluginRetryKey string) (encoding.PipelineExecutionState, [][]byte, encoding.ErrCode, bool, time.Duration, error) {
resultLen := len(streamsLookup.Feeds)
ch := make(chan mercury.MercuryData, resultLen)
if len(streamsLookup.Feeds) == 0 {
Expand Down Expand Up @@ -107,7 +108,7 @@ func (c *client) DoRequest(ctx context.Context, streamsLookup *mercury.StreamsLo
return state, nil, errCode, retryable, 0 * time.Second, reqErr
}
// If errors were retryable then calculate retry interval
retryInterval := mercury.CalculateRetryConfigFn(pluginRetryKey, c.mercuryConfig)
retryInterval := mercury.CalculateRetryConfigFn(upkeepType, pluginRetryKey, c.mercuryConfig)
if retryInterval != mercury.RetryIntervalTimeout {
// Return the retyrable state with appropriate retry interval
return state, nil, errCode, retryable, retryInterval, reqErr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"testing"
"time"

automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types"
"github.com/smartcontractkit/chainlink-common/pkg/types"

"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -457,7 +458,7 @@ func TestV02_DoMercuryRequestV02(t *testing.T) {
c.httpClient = hc

reason := encoding.UpkeepFailureReasonNone // TODO: Fix test
state, values, errCode, retryable, retryInterval, reqErr := c.DoRequest(testutils.Context(t), tt.lookup, tt.pluginRetryKey)
state, values, errCode, retryable, retryInterval, reqErr := c.DoRequest(testutils.Context(t), tt.lookup, automationTypes.ConditionTrigger, tt.pluginRetryKey)
assert.Equal(t, tt.expectedValues, values)
assert.Equal(t, tt.expectedRetryable, retryable)
if retryable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"github.com/avast/retry-go/v4"
"github.com/ethereum/go-ethereum/common/hexutil"

automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types"

"github.com/smartcontractkit/chainlink-common/pkg/services"

"github.com/smartcontractkit/chainlink/v2/core/logger"
Expand Down Expand Up @@ -61,7 +63,7 @@ func NewClient(mercuryConfig mercury.MercuryConfigProvider, httpClient mercury.H
}
}

func (c *client) DoRequest(ctx context.Context, streamsLookup *mercury.StreamsLookup, pluginRetryKey string) (encoding.PipelineExecutionState, [][]byte, encoding.ErrCode, bool, time.Duration, error) {
func (c *client) DoRequest(ctx context.Context, streamsLookup *mercury.StreamsLookup, upkeepType automationTypes.UpkeepType, pluginRetryKey string) (encoding.PipelineExecutionState, [][]byte, encoding.ErrCode, bool, time.Duration, error) {
if len(streamsLookup.Feeds) == 0 {
return encoding.NoPipelineError, [][]byte{}, encoding.ErrCodeStreamsBadRequest, false, 0 * time.Second, nil
}
Expand All @@ -79,7 +81,7 @@ func (c *client) DoRequest(ctx context.Context, streamsLookup *mercury.StreamsLo
return m.State, nil, m.ErrCode, m.Retryable, 0 * time.Second, m.Error
}
// If errors were retryable then calculate retry interval
retryInterval := mercury.CalculateRetryConfigFn(pluginRetryKey, c.mercuryConfig)
retryInterval := mercury.CalculateRetryConfigFn(upkeepType, pluginRetryKey, c.mercuryConfig)
if retryInterval != mercury.RetryIntervalTimeout {
// Return the retyrable state with appropriate retry interval
return m.State, nil, m.ErrCode, m.Retryable, retryInterval, m.Error
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"
"time"

automationTypes "github.com/smartcontractkit/chainlink-automation/pkg/v3/types"
"github.com/smartcontractkit/chainlink-common/pkg/types"

"github.com/ethereum/go-ethereum/common/hexutil"
Expand Down Expand Up @@ -165,7 +166,7 @@ func TestV03_DoMercuryRequestV03(t *testing.T) {
c.httpClient = hc

reason := encoding.UpkeepFailureReasonNone // TODO: Fix test
state, values, errCode, retryable, retryInterval, reqErr := c.DoRequest(testutils.Context(t), tt.lookup, tt.pluginRetryKey)
state, values, errCode, retryable, retryInterval, reqErr := c.DoRequest(testutils.Context(t), tt.lookup, automationTypes.ConditionTrigger, tt.pluginRetryKey)

assert.Equal(t, tt.expectedValues, values)
assert.Equal(t, tt.expectedRetryable, retryable)
Expand Down

0 comments on commit 783ed9c

Please sign in to comment.