@@ -141,6 +141,9 @@ impl From<&SolanaAccountMeta> for anchor_lang::prelude::AccountMeta {
141141 }
142142}
143143
144+ /// Maximum number of accounts allowed in a [`GmpSolanaPayload`]
145+ pub const MAX_GMP_SOLANA_PAYLOAD_ACCOUNTS : usize = 32 ;
146+
144147/// Domain type for GMP Solana payload with type-safe fields
145148#[ derive( Debug , Clone ) ]
146149pub struct GmpSolanaPayload {
@@ -185,6 +188,10 @@ impl TryFrom<RawGmpSolanaPayload> for GmpSolanaPayload {
185188 return Err ( GmpValidationError :: EmptyPayload ) ;
186189 }
187190
191+ if raw. accounts . len ( ) > MAX_GMP_SOLANA_PAYLOAD_ACCOUNTS {
192+ return Err ( GmpValidationError :: TooManyAccounts ) ;
193+ }
194+
188195 let mut accounts = Vec :: with_capacity ( raw. accounts . len ( ) ) ;
189196 for account in raw. accounts {
190197 let pubkey = Pubkey :: try_from ( & account. pubkey [ ..] )
@@ -213,3 +220,39 @@ impl GmpAcknowledgement {
213220 Self { result }
214221 }
215222}
223+
224+ #[ cfg( test) ]
225+ mod tests {
226+ use super :: * ;
227+
228+ fn valid_account ( ) -> RawSolanaAccountMeta {
229+ RawSolanaAccountMeta {
230+ pubkey : vec ! [ 0u8 ; 32 ] ,
231+ is_signer : false ,
232+ is_writable : false ,
233+ }
234+ }
235+
236+ #[ test]
237+ fn try_from_rejects_too_many_accounts ( ) {
238+ let raw = RawGmpSolanaPayload {
239+ data : vec ! [ 1 ] ,
240+ accounts : vec ! [ valid_account( ) ; MAX_GMP_SOLANA_PAYLOAD_ACCOUNTS + 1 ] ,
241+ prefund_lamports : 0 ,
242+ } ;
243+ assert_eq ! (
244+ GmpSolanaPayload :: try_from( raw) . unwrap_err( ) ,
245+ GmpValidationError :: TooManyAccounts ,
246+ ) ;
247+ }
248+
249+ #[ test]
250+ fn try_from_accepts_max_accounts ( ) {
251+ let raw = RawGmpSolanaPayload {
252+ data : vec ! [ 1 ] ,
253+ accounts : vec ! [ valid_account( ) ; MAX_GMP_SOLANA_PAYLOAD_ACCOUNTS ] ,
254+ prefund_lamports : 0 ,
255+ } ;
256+ assert ! ( GmpSolanaPayload :: try_from( raw) . is_ok( ) ) ;
257+ }
258+ }
0 commit comments