Skip to content

Commit

Permalink
Fix flaky ccip tests (#15432)
Browse files Browse the repository at this point in the history
* minor change to trigger ci

* minor change to trigger ci

* retry until native fee is sufficient

* trigger ci
  • Loading branch information
dimkouv authored Nov 27, 2024
1 parent 38e3681 commit 81b3541
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 12 deletions.
57 changes: 45 additions & 12 deletions deployment/ccip/changeset/test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"
"net/http/httptest"
"sort"
"strings"
"testing"
"time"

Expand All @@ -16,6 +17,7 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/pkg/errors"
"github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers"

"github.com/smartcontractkit/chainlink-ccip/pluginconfig"

commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config"
Expand Down Expand Up @@ -398,19 +400,12 @@ func CCIPSendRequest(
if testRouter {
r = state.Chains[src].TestRouter
}
fee, err := r.GetFee(
&bind.CallOpts{Context: context.Background()}, dest, msg)
if err != nil {
return nil, 0, errors.Wrap(deployment.MaybeDataErr(err), "failed to get fee")
}
if msg.FeeToken == common.HexToAddress("0x0") {
e.Chains[src].DeployerKey.Value = fee
defer func() { e.Chains[src].DeployerKey.Value = nil }()

if msg.FeeToken == common.HexToAddress("0x0") { // fee is in native token
return retryCcipSendUntilNativeFeeIsSufficient(e, r, src, dest, msg)
}
tx, err := r.CcipSend(
e.Chains[src].DeployerKey,
dest,
msg)

tx, err := r.CcipSend(e.Chains[src].DeployerKey, dest, msg)
if err != nil {
return nil, 0, errors.Wrap(err, "failed to send CCIP message")
}
Expand All @@ -421,6 +416,44 @@ func CCIPSendRequest(
return tx, blockNum, nil
}

// retryCcipSendUntilNativeFeeIsSufficient sends a CCIP message with a native fee,
// and retries until the fee is sufficient. This is due to the fact that the fee is not known in advance,
// and the message will be rejected if the fee is insufficient.
func retryCcipSendUntilNativeFeeIsSufficient(
e deployment.Environment,
r *router.Router,
src,
dest uint64,
msg router.ClientEVM2AnyMessage,
) (*types.Transaction, uint64, error) {
const errCodeInsufficientFee = "0x07da6ee6"
defer func() { e.Chains[src].DeployerKey.Value = nil }()

for {
fee, err := r.GetFee(&bind.CallOpts{Context: context.Background()}, dest, msg)
if err != nil {
return nil, 0, errors.Wrap(deployment.MaybeDataErr(err), "failed to get fee")
}

e.Chains[src].DeployerKey.Value = fee

tx, err := r.CcipSend(e.Chains[src].DeployerKey, dest, msg)
if err != nil {
return nil, 0, errors.Wrap(err, "failed to send CCIP message")
}

blockNum, err := e.Chains[src].Confirm(tx)
if err != nil {
if strings.Contains(err.Error(), errCodeInsufficientFee) {
continue
}
return nil, 0, errors.Wrap(err, "failed to confirm CCIP message")
}

return tx, blockNum, nil
}
}

// CCIPSendCalldata packs the calldata for the Router's ccipSend method.
// This is expected to be used in Multicall scenarios (i.e multiple ccipSend calls
// in a single transaction).
Expand Down
2 changes: 2 additions & 0 deletions integration-tests/smoke/ccip/ccip_rmn_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,8 @@ const (
func runRmnTestCase(t *testing.T, tc rmnTestCase) {
require.NoError(t, os.Setenv("ENABLE_RMN", "true"))

t.Logf("Running RMN test case: %s", tc.name)

envWithRMN, rmnCluster := testsetups.NewLocalDevEnvironmentWithRMN(t, logger.TestLogger(t), len(tc.rmnNodes))
t.Logf("envWithRmn: %#v", envWithRMN)

Expand Down

0 comments on commit 81b3541

Please sign in to comment.