Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CCIP-4160 Token Transfer Tests #15278

Merged
merged 36 commits into from
Nov 29, 2024

Conversation

0xsuryansh
Copy link
Member

@0xsuryansh 0xsuryansh commented Nov 18, 2024

CCIP Integration test covering the following scenarios

  1. Send token to EOA
  2. Send token to contract
  3. Send 2 tokens to receiver
  4. Send N tokens to contract

@0xsuryansh 0xsuryansh changed the title CCIP-4160 test refactoring CCIP-4160 Token Transfer Tests Nov 18, 2024
Copy link
Contributor

github-actions bot commented Nov 18, 2024

AER Report: CI Core ran successfully ✅

aer_workflow , commit

AER Report: Operator UI CI ran successfully ✅

aer_workflow , commit

@0xsuryansh 0xsuryansh force-pushed the CCIP-4160_Implement_token_transfer_tests branch from 99c3452 to 3bfac63 Compare November 19, 2024 11:33
@0xsuryansh 0xsuryansh marked this pull request as ready for review November 19, 2024 11:35
@0xsuryansh 0xsuryansh requested review from a team as code owners November 19, 2024 11:35
Copy link
Collaborator

@mateusz-sekara mateusz-sekara left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job, some minor comments

integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
integration-tests/smoke/ccip_test.go Outdated Show resolved Hide resolved
@mateusz-sekara mateusz-sekara requested a review from a team as a code owner November 28, 2024 12:32
mateusz-sekara
mateusz-sekara previously approved these changes Nov 28, 2024
dimkouv
dimkouv previously approved these changes Nov 28, 2024
Copy link
Contributor

@dimkouv dimkouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly minor comments, approving. Feel free to resolve and re-request review if you agree with any.

deployment/ccip/changeset/test_helpers.go Outdated Show resolved Hide resolved
expectedSeqNum := make(map[SourceDestPair]uint64)
expectedSeqNumExec := make(map[SourceDestPair][]uint64)

latesthdr, err := env.Chains[destChain].Client.HeaderByNumber(testcontext.Get(t), nil)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe better to pass ctx to this func?

require.NoError(t, err)

require.Eventually(t, func() bool {
actualBalance, err := tokenContract.BalanceOf(&bind.CallOpts{Context: tests.Context(t)}, receiver)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe pass ctx to this func? to avoid getting a new one everyime.

tokenContract, err := burn_mint_erc677.NewBurnMintERC677(token, chain.Client)
require.NoError(t, err)

balance, err := tokenContract.BalanceOf(&bind.CallOpts{Context: tests.Context(t)}, receiver)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar for ctx

inMemoryEnv := false

// use this if you are testing locally in memory
// tenv := changeset.NewMemoryEnvironmentWithJobsAndContracts(t, lggr, 2, 4, config)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be better if we can do this using some env var. So we can easily switch in CI or run without touching code.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we've covered that somewhere in the convo. There is a ticket to do it with env variable. Let's address it later

selfServeDestTokenPoolDeployer,
state,
e.ExistingAddresses,
"SELF_SERVE_TOKEN",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same


tinyOneCoin := new(big.Int).SetUint64(1)

// Test scenarios are defined here
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment probably not necessary, it's obvious

tokenAmounts: []router.ClientEVMTokenAmount{
{
Token: srcToken.Address(),
Amount: tinyOneCoin,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Name is a bit confusing for me tinyOneCoin maybe just one and oneE18, fiveE18 etc ?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, should be just oneCoin. I think it was copypasted from USDC which required always to pass exactly 1 because this value is hardcoded in the mocked contracts

},
receiver: state.Chains[sourceChain].Receiver.Address(),
expectedTokenBalances: map[common.Address]*big.Int{
selfServeSrcToken.Address(): new(big.Int).SetUint64(2),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can set two to a variable to follow same pattern with tinyOneCoin

require.NoError(t, err)

// Simulated backend sets chainID to 1337 always
chainID := big.NewInt(1337)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i believe it's similar for the commented out environment setup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should assume this chain ID here, these tests, in theory, can run on real chains.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be moved to test_setups. Right now we run it only on simulated or docker. If not simulated env is used we set proper chainID. I'm gonna work as followup to extract it somewhere

@@ -75,134 +73,3 @@ func TestInitialDeployOnLocal(t *testing.T) {

// TODO: Apply the proposal.
}

func TestTokenTransfer(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 191 to 216
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
initialBalances := map[common.Address]*big.Int{}
for token := range scenario.expectedTokenBalances {
initialBalance := changeset.GetTokenBalance(t, token, scenario.receiver, e.Chains[scenario.dstChain])
initialBalances[token] = initialBalance
}

changeset.TransferAndWaitForSuccess(
t,
e,
state,
scenario.srcChain,
scenario.dstChain,
scenario.tokenAmounts,
scenario.receiver,
scenario.data,
scenario.expectedExecutionState,
)

for token, balance := range scenario.expectedTokenBalances {
expected := new(big.Int).Add(initialBalances[token], balance)
changeset.WaitForTheTokenBalance(t, token, scenario.receiver, e.Chains[scenario.dstChain], expected)
}
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This approach is quite sequential. I would recommend splitting this test into multiple smaller tests and enabling parallel execution.

A few options we could consider include:

  1. Using multiple wallet addresses.
  2. Breaking the test into separate segments (though this will require repeating the setup), and assigning a dedicated runner for each segment. This would reduce the overall execution time, as the message processing wait time can be parallelized across the different tests. With this approach, we could potentially achieve at least a 3x speedup.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have to figure out a way to do parallel tests that doesn't mean we repeat a ton of test setup and no flakiness

0xnogo
0xnogo previously approved these changes Nov 29, 2024
}

// TransferAndWaitForSuccess sends a message from sourceChain to destChain and waits for it to be executed
func TransferAndWaitForSuccess(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a ticket to move all these funcs out of changeset and into a cciptesthelpers package or something, changeset is supposed to be the public API and shouldn't have these kinda funcs.

require.Equal(t, expectedStatus, states[identifier][msgSentEvent.SequenceNumber])
}

func WaitForTheTokenBalance(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: WaitForTokenBalance without the The

Comment on lines 191 to 216
for _, scenario := range scenarios {
t.Run(scenario.name, func(t *testing.T) {
initialBalances := map[common.Address]*big.Int{}
for token := range scenario.expectedTokenBalances {
initialBalance := changeset.GetTokenBalance(t, token, scenario.receiver, e.Chains[scenario.dstChain])
initialBalances[token] = initialBalance
}

changeset.TransferAndWaitForSuccess(
t,
e,
state,
scenario.srcChain,
scenario.dstChain,
scenario.tokenAmounts,
scenario.receiver,
scenario.data,
scenario.expectedExecutionState,
)

for token, balance := range scenario.expectedTokenBalances {
expected := new(big.Int).Add(initialBalances[token], balance)
changeset.WaitForTheTokenBalance(t, token, scenario.receiver, e.Chains[scenario.dstChain], expected)
}
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have to figure out a way to do parallel tests that doesn't mean we repeat a ton of test setup and no flakiness

require.NoError(t, err)

// Simulated backend sets chainID to 1337 always
chainID := big.NewInt(1337)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should assume this chain ID here, these tests, in theory, can run on real chains.

@mateusz-sekara mateusz-sekara dismissed stale reviews from 0xnogo, dimkouv, and themself via b870f35 November 29, 2024 10:08
@mateusz-sekara mateusz-sekara added this pull request to the merge queue Nov 29, 2024
Merged via the queue into develop with commit 5633382 Nov 29, 2024
174 of 175 checks passed
@mateusz-sekara mateusz-sekara deleted the CCIP-4160_Implement_token_transfer_tests branch November 29, 2024 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants