Skip to content

Commit 4e6d7ad

Browse files
authored
integration-tests/smoke/ccip: add max batch size test (smartcontractkit#15403)
* add max batch size test * fix lint
1 parent 3230f2a commit 4e6d7ad

File tree

1 file changed

+142
-19
lines changed

1 file changed

+142
-19
lines changed

integration-tests/smoke/ccip/ccip_batching_test.go

+142-19
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,19 @@ import (
99

1010
"github.com/ethereum/go-ethereum/accounts/abi/bind"
1111
"github.com/ethereum/go-ethereum/common"
12+
gethtypes "github.com/ethereum/go-ethereum/core/types"
13+
"github.com/ethereum/go-ethereum/crypto"
1214
"github.com/stretchr/testify/require"
1315
"golang.org/x/exp/maps"
1416

15-
"github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"
17+
chainsel "github.com/smartcontractkit/chain-selectors"
1618

19+
"github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3"
20+
"github.com/smartcontractkit/chainlink-common/pkg/merklemulti"
1721
"github.com/smartcontractkit/chainlink/deployment"
1822
"github.com/smartcontractkit/chainlink/deployment/ccip/changeset"
1923
"github.com/smartcontractkit/chainlink/integration-tests/testsetups"
24+
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
2025
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp"
2126
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp"
2227
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router"
@@ -63,21 +68,20 @@ func Test_CCIPBatching(t *testing.T) {
6368
sourceChain1: 1,
6469
sourceChain2: 1,
6570
}
66-
endSeqNum = map[uint64]ccipocr3.SeqNum{
67-
sourceChain1: ccipocr3.SeqNum(numMessages),
68-
sourceChain2: ccipocr3.SeqNum(numMessages),
69-
}
7071
)
7172

7273
t.Run("batch data only messages from single source", func(t *testing.T) {
74+
var (
75+
sourceChain = sourceChain1
76+
)
7377
err := sendMessages(
7478
ctx,
7579
t,
76-
e.Env.Chains[sourceChain1],
77-
e.Env.Chains[sourceChain1].DeployerKey,
78-
state.Chains[sourceChain1].OnRamp,
79-
state.Chains[sourceChain1].Router,
80-
state.Chains[sourceChain1].Multicall3,
80+
e.Env.Chains[sourceChain],
81+
e.Env.Chains[sourceChain].DeployerKey,
82+
state.Chains[sourceChain].OnRamp,
83+
state.Chains[sourceChain].Router,
84+
state.Chains[sourceChain].Multicall3,
8185
destChain,
8286
numMessages,
8387
common.LeftPadBytes(state.Chains[destChain].Receiver.Address().Bytes(), 32),
@@ -86,30 +90,29 @@ func Test_CCIPBatching(t *testing.T) {
8690

8791
_, err = changeset.ConfirmCommitWithExpectedSeqNumRange(
8892
t,
89-
e.Env.Chains[sourceChain1],
93+
e.Env.Chains[sourceChain],
9094
e.Env.Chains[destChain],
9195
state.Chains[destChain].OffRamp,
9296
nil,
93-
ccipocr3.NewSeqNumRange(startSeqNum[sourceChain1], endSeqNum[sourceChain1]),
97+
ccipocr3.NewSeqNumRange(startSeqNum[sourceChain], startSeqNum[sourceChain]+numMessages-1),
9498
)
95-
require.NoErrorf(t, err, "failed to confirm commit from chain %d", sourceChain1)
99+
require.NoErrorf(t, err, "failed to confirm commit from chain %d", sourceChain)
96100

97101
states, err := changeset.ConfirmExecWithSeqNrs(
98102
t,
99-
e.Env.Chains[sourceChain1],
103+
e.Env.Chains[sourceChain],
100104
e.Env.Chains[destChain],
101105
state.Chains[destChain].OffRamp,
102106
nil,
103-
genSeqNrRange(startSeqNum[sourceChain1], endSeqNum[sourceChain1]),
107+
genSeqNrRange(startSeqNum[sourceChain], startSeqNum[sourceChain]+numMessages-1),
104108
)
105109
require.NoError(t, err)
106110
// assert that all states are successful
107111
for _, state := range states {
108112
require.Equal(t, changeset.EXECUTION_STATE_SUCCESS, state)
109113
}
110114

111-
startSeqNum[sourceChain1] = endSeqNum[sourceChain1] + 1
112-
endSeqNum[sourceChain1] = startSeqNum[sourceChain1] + ccipocr3.SeqNum(numMessages) - 1
115+
startSeqNum[sourceChain] = startSeqNum[sourceChain] + numMessages
113116
})
114117

115118
t.Run("batch data only messages from multiple sources", func(t *testing.T) {
@@ -158,7 +161,7 @@ func Test_CCIPBatching(t *testing.T) {
158161
srcChain,
159162
destChain,
160163
startSeqNum[srcChain],
161-
endSeqNum[srcChain],
164+
startSeqNum[srcChain]+ccipocr3.SeqNum(numMessages)-1,
162165
&wg,
163166
outputErrs,
164167
)
@@ -198,7 +201,7 @@ func Test_CCIPBatching(t *testing.T) {
198201
state,
199202
srcChain,
200203
destChain,
201-
genSeqNrRange(startSeqNum[srcChain], endSeqNum[srcChain]),
204+
genSeqNrRange(startSeqNum[srcChain], startSeqNum[srcChain]+ccipocr3.SeqNum(numMessages)-1),
202205
&wg,
203206
execErrs,
204207
)
@@ -226,6 +229,77 @@ func Test_CCIPBatching(t *testing.T) {
226229
require.Equal(t, changeset.EXECUTION_STATE_SUCCESS, state)
227230
}
228231
}
232+
233+
// update the start and end seq nums
234+
for _, srcChain := range sourceChains {
235+
startSeqNum[srcChain] = startSeqNum[srcChain] + numMessages
236+
}
237+
})
238+
239+
t.Run("max evm batch size", func(t *testing.T) {
240+
var (
241+
sourceChain = sourceChain1
242+
otherSender = mustNewTransactor(t, e.Env.Chains[sourceChain])
243+
transactors = []*bind.TransactOpts{
244+
e.Env.Chains[sourceChain].DeployerKey,
245+
otherSender,
246+
}
247+
errs = make(chan error, len(transactors))
248+
)
249+
250+
// transfer some eth to the other sender from the DeployerKey
251+
sendEth(
252+
ctx,
253+
t,
254+
e.Env.Chains[sourceChain],
255+
e.Env.Chains[sourceChain].DeployerKey,
256+
otherSender.From,
257+
assets.Ether(20).ToInt(),
258+
)
259+
260+
for _, transactor := range transactors {
261+
go func() {
262+
err := sendMessages(
263+
ctx,
264+
t,
265+
e.Env.Chains[sourceChain],
266+
transactor,
267+
state.Chains[sourceChain].OnRamp,
268+
state.Chains[sourceChain].Router,
269+
state.Chains[sourceChain].Multicall3,
270+
destChain,
271+
merklemulti.MaxNumberTreeLeaves/2,
272+
common.LeftPadBytes(state.Chains[destChain].Receiver.Address().Bytes(), 32),
273+
)
274+
t.Log("sendMessages error:", err, ", writing to channel")
275+
errs <- err
276+
t.Log("sent error to channel")
277+
}()
278+
}
279+
280+
var i = 0
281+
for i < len(transactors) {
282+
select {
283+
case err := <-errs:
284+
require.NoError(t, err)
285+
i++
286+
case <-ctx.Done():
287+
require.FailNow(t, "didn't get all errors before test context was done")
288+
}
289+
}
290+
291+
_, err = changeset.ConfirmCommitWithExpectedSeqNumRange(
292+
t,
293+
e.Env.Chains[sourceChain],
294+
e.Env.Chains[destChain],
295+
state.Chains[destChain].OffRamp,
296+
nil, // startBlock
297+
ccipocr3.NewSeqNumRange(
298+
startSeqNum[sourceChain],
299+
startSeqNum[sourceChain]+ccipocr3.SeqNum(merklemulti.MaxNumberTreeLeaves)-1,
300+
),
301+
)
302+
require.NoErrorf(t, err, "failed to confirm commit from chain %d", sourceChain)
229303
})
230304
}
231305

@@ -333,6 +407,7 @@ func sendMessages(
333407
}
334408

335409
// Send the tx with the messages through the multicall
410+
t.Logf("Sending %d messages with total value %s", numMessages, totalValue.String())
336411
tx, err := sourceMulticall3.Aggregate3Value(
337412
&bind.TransactOpts{
338413
From: sourceTransactOpts.From,
@@ -414,3 +489,51 @@ func genSeqNrRange(start, end ccipocr3.SeqNum) []uint64 {
414489
}
415490
return seqNrs
416491
}
492+
493+
func mustNewTransactor(t *testing.T, chain deployment.Chain) *bind.TransactOpts {
494+
chainID, err := chainsel.GetChainIDFromSelector(chain.Selector)
495+
require.NoError(t, err)
496+
chainIDBig, ok := new(big.Int).SetString(chainID, 10)
497+
require.True(t, ok, "evm chainID must be integral")
498+
key, err := crypto.GenerateKey()
499+
require.NoError(t, err)
500+
transactor, err := bind.NewKeyedTransactorWithChainID(key, chainIDBig)
501+
require.NoError(t, err)
502+
return transactor
503+
}
504+
505+
func sendEth(
506+
ctx context.Context,
507+
t *testing.T,
508+
chain deployment.Chain,
509+
from *bind.TransactOpts,
510+
to common.Address,
511+
value *big.Int,
512+
) {
513+
balance, err := chain.Client.BalanceAt(ctx, from.From, nil)
514+
require.NoError(t, err)
515+
if balance.Cmp(value) < 0 {
516+
t.Fatalf("insufficient balance: %s < %s", balance.String(), value.String())
517+
}
518+
t.Logf("balance of from account %s: %s", from.From.String(), balance.String())
519+
520+
nonce, err := chain.Client.PendingNonceAt(ctx, from.From)
521+
require.NoError(t, err)
522+
gp, err := chain.Client.SuggestGasPrice(ctx)
523+
require.NoError(t, err)
524+
tx := gethtypes.NewTx(&gethtypes.LegacyTx{
525+
Nonce: nonce,
526+
GasPrice: gp,
527+
Gas: 21_000,
528+
To: &to,
529+
Value: value,
530+
Data: nil,
531+
})
532+
signedTx, err := from.Signer(from.From, tx)
533+
require.NoError(t, err)
534+
err = chain.Client.SendTransaction(ctx, signedTx)
535+
require.NoError(t, err)
536+
t.Log("sent funding tx:", signedTx.Hash().Hex())
537+
_, err = deployment.ConfirmIfNoError(chain, signedTx, err)
538+
require.NoError(t, err)
539+
}

0 commit comments

Comments
 (0)