Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
solana: validate evm extra args
Browse files Browse the repository at this point in the history
aalu1418 committed Jan 21, 2025

Verified

This commit was signed with the committer’s verified signature.
aalu1418 Aaron Lu
1 parent 5d987b7 commit 6ff89e0
Showing 5 changed files with 108 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -120,6 +120,20 @@ pub mod ramps {
CcipRouterError::UnsupportedNumberOfTokens
);

require_gte!(
dest_chain.config.max_per_msg_gas_limit as u128,
msg.extra_args
.gas_limit
.unwrap_or(dest_chain.config.default_tx_gas_limit as u128),
CcipRouterError::MessageGasLimitTooHigh,
);

require!(
!dest_chain.config.enforce_out_of_order
|| msg.extra_args.allow_out_of_order_execution.unwrap_or(false),
CcipRouterError::ExtraArgOutOfOrderExecutionMustBeTrue,
);

validate_dest_family_address(msg, dest_chain.config.chain_family_selector)
}

4 changes: 4 additions & 0 deletions chains/solana/contracts/programs/ccip-router/src/lib.rs
Original file line number Diff line number Diff line change
@@ -683,4 +683,8 @@ pub enum CcipRouterError {
MessageFeeTooHigh,
#[msg("Source token data is too large")]
SourceTokenDataTooLarge,
#[msg("Message gas limit too high")]
MessageGasLimitTooHigh,
#[msg("Extra arg out of order execution must be true")]
ExtraArgOutOfOrderExecutionMustBeTrue,
}
6 changes: 6 additions & 0 deletions chains/solana/contracts/target/idl/ccip_router.json
Original file line number Diff line number Diff line change
@@ -2773,6 +2773,12 @@
},
{
"name": "SourceTokenDataTooLarge"
},
{
"name": "MessageGasLimitTooHigh"
},
{
"name": "ExtraArgOutOfOrderExecutionMustBeTrue"
}
]
}
79 changes: 78 additions & 1 deletion chains/solana/contracts/tests/ccip/ccip_router_test.go
Original file line number Diff line number Diff line change
@@ -56,6 +56,7 @@ func TestCCIPRouter(t *testing.T) {
require.NoError(t, gerr)

var nonceEvmPDA solana.PublicKey
var nonceSvmPDA solana.PublicKey

// billing
type AccountsPerToken struct {
@@ -393,6 +394,8 @@ func TestCCIPRouter(t *testing.T) {

nonceEvmPDA, err = ccip.GetNoncePDA(config.EvmChainSelector, user.PublicKey())
require.NoError(t, err)
nonceSvmPDA, err = ccip.GetNoncePDA(config.SVMChainSelector, user.PublicKey())
require.NoError(t, err)
})

t.Run("When admin updates the default gas limit it's updated", func(t *testing.T) {
@@ -586,7 +589,9 @@ func TestCCIPRouter(t *testing.T) {
// minimal valid config
DefaultTxGasLimit: 1,
MaxPerMsgGasLimit: 100,
ChainFamilySelector: [4]uint8{3, 2, 1, 0}},
ChainFamilySelector: [4]uint8{3, 2, 1, 0},
EnforceOutOfOrder: true,
},
config.SVMSourceChainStatePDA,
config.SVMDestChainStatePDA,
config.RouterConfigPDA,
@@ -2374,6 +2379,78 @@ func TestCCIPRouter(t *testing.T) {
require.Equal(t, uint64(3), ccipMessageSentEvent.Message.Header.Nonce)
})

t.Run("When gasLimit is too high, it fails", func(t *testing.T) {
destinationChainSelector := config.EvmChainSelector
destinationChainStatePDA := config.EvmDestChainStatePDA
message := ccip_router.SVM2AnyMessage{
FeeToken: token2022.mint,
Receiver: validReceiverAddress[:],
Data: []byte{4, 5, 6},
ExtraArgs: ccip_router.ExtraArgsInput{
GasLimit: &bin.Uint128{Lo: 0, Hi: 1_000_000_000},
},
}

raw := ccip_router.NewCcipSendInstruction(
destinationChainSelector,
message,
[]byte{},
config.RouterConfigPDA,
destinationChainStatePDA,
nonceEvmPDA,
user.PublicKey(),
solana.SystemProgramID,
token2022.program,
token2022.mint,
token2022.billingConfigPDA,
token2022.billingConfigPDA,
token2022.userATA,
token2022.billingATA,
config.BillingSignerPDA,
config.ExternalTokenPoolsSignerPDA,
)
raw.GetFeeTokenUserAssociatedAccountAccount().WRITE()
instruction, err := raw.ValidateAndBuild()
require.NoError(t, err)
testutils.SendAndFailWith(ctx, t, solanaGoClient, []solana.Instruction{instruction}, user, config.DefaultCommitment, []string{ccip_router.MessageGasLimitTooHigh_CcipRouterError.String()})
})

t.Run("When out of order execution is enforced, it fails when not enabled", func(t *testing.T) {
destinationChainSelector := config.SVMChainSelector // SVM dest chain requires out of order execution
destinationChainStatePDA := config.SVMDestChainStatePDA
falseVal := false
message := ccip_router.SVM2AnyMessage{
FeeToken: token2022.mint,
Receiver: validReceiverAddress[:],
ExtraArgs: ccip_router.ExtraArgsInput{
AllowOutOfOrderExecution: &falseVal,
},
}

raw := ccip_router.NewCcipSendInstruction(
destinationChainSelector,
message,
[]byte{},
config.RouterConfigPDA,
destinationChainStatePDA,
nonceSvmPDA,
user.PublicKey(),
solana.SystemProgramID,
token2022.program,
token2022.mint,
token2022.billingConfigPDA,
token2022.billingConfigPDA,
token2022.userATA,
token2022.billingATA,
config.BillingSignerPDA,
config.ExternalTokenPoolsSignerPDA,
)
raw.GetFeeTokenUserAssociatedAccountAccount().WRITE()
instruction, err := raw.ValidateAndBuild()
require.NoError(t, err)
testutils.SendAndFailWith(ctx, t, solanaGoClient, []solana.Instruction{instruction}, user, config.DefaultCommitment, []string{ccip_router.ExtraArgOutOfOrderExecutionMustBeTrue_CcipRouterError.String()})
})

t.Run("When sending a message with an invalid nonce account, it fails", func(t *testing.T) {
destinationChainSelector := config.EvmChainSelector
destinationChainStatePDA := config.EvmDestChainStatePDA
6 changes: 6 additions & 0 deletions chains/solana/gobindings/ccip_router/types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6ff89e0

Please sign in to comment.