-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
CCIP-4160 Token Transfer Tests #15278
Conversation
AER Report: CI Core ran successfully ✅AER Report: Operator UI CI ran successfully ✅ |
99c3452
to
3bfac63
Compare
There was a problem hiding this 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
# Conflicts: # integration-tests/smoke/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip/ccip_test.go
# Conflicts: # integration-tests/smoke/ccip/ccip_test.go
There was a problem hiding this 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.
expectedSeqNum := make(map[SourceDestPair]uint64) | ||
expectedSeqNumExec := make(map[SourceDestPair][]uint64) | ||
|
||
latesthdr, err := env.Chains[destChain].Client.HeaderByNumber(testcontext.Get(t), nil) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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, |
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: As we moved out this test, the parallel count here can be reduced to one. https://github.com/smartcontractkit/chainlink/pull/15278/files#diff-c97a5a0f8e46926381c7f53223fb048419a40e9c9b8e243b3f49e15bc2e00d9eL945
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) | ||
} | ||
}) | ||
} |
There was a problem hiding this comment.
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:
- Using multiple wallet addresses.
- 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.
There was a problem hiding this comment.
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
} | ||
|
||
// TransferAndWaitForSuccess sends a message from sourceChain to destChain and waits for it to be executed | ||
func TransferAndWaitForSuccess( |
There was a problem hiding this comment.
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( |
There was a problem hiding this comment.
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
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) | ||
} | ||
}) | ||
} |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
b870f35
CCIP Integration test covering the following scenarios