@@ -476,4 +476,69 @@ mod tests {
476476 . 0 ,
477477 ) ;
478478 }
479+
480+ #[ test]
481+ #[ ignore]
482+ fn no_stack_overflow_when_decoding_nested_call_during_dispatch ( ) {
483+ // this test is normally ignored, because it only makes sense to run it in release mode
484+
485+ let mut ext: sp_io:: TestExternalities =
486+ SystemConfig :: default ( ) . build_storage :: < Runtime > ( ) . unwrap ( ) . into ( ) ;
487+ ext. execute_with ( || {
488+ let bridge = MILLAU_CHAIN_ID ;
489+
490+ let mut call: Call = SystemCall :: set_heap_pages { pages : 64 } . into ( ) ;
491+
492+ for _i in 0 ..3000 {
493+ call = Call :: Sudo ( pallet_sudo:: Call :: sudo { call : Box :: new ( call) } ) ;
494+ }
495+
496+ let dispatch_weight = 500 ;
497+ let dispatch_fee = <Runtime as pallet_transaction_payment:: Config >:: WeightToFee :: calc (
498+ & dispatch_weight,
499+ ) ;
500+ assert ! ( dispatch_fee > 0 ) ;
501+
502+ // create relayer account with minimal balance
503+ let relayer_account: AccountId = [ 1u8 ; 32 ] . into ( ) ;
504+ let initial_amount = ExistentialDeposit :: get ( ) ;
505+ let _ = <pallet_balances:: Pallet < Runtime > as Currency < AccountId > >:: deposit_creating (
506+ & relayer_account,
507+ initial_amount,
508+ ) ;
509+
510+ // create dispatch account with minimal balance + dispatch fee
511+ let dispatch_account = derive_account_id :: <
512+ <Runtime as pallet_bridge_dispatch:: Config >:: SourceChainAccountId ,
513+ > ( bridge, SourceAccount :: Root ) ;
514+ let dispatch_account =
515+ <Runtime as pallet_bridge_dispatch:: Config >:: AccountIdConverter :: convert (
516+ dispatch_account,
517+ ) ;
518+ let _ = <pallet_balances:: Pallet < Runtime > as Currency < AccountId > >:: deposit_creating (
519+ & dispatch_account,
520+ initial_amount + dispatch_fee,
521+ ) ;
522+
523+ // dispatch message with intention to pay dispatch fee at the target chain
524+ //
525+ // this is where the stack overflow has happened before the fix has been applied
526+ FromMillauMessageDispatch :: dispatch (
527+ & relayer_account,
528+ DispatchMessage {
529+ key : MessageKey { lane_id : Default :: default ( ) , nonce : 0 } ,
530+ data : DispatchMessageData {
531+ payload : Ok ( FromBridgedChainMessagePayload :: < WithMillauMessageBridge > {
532+ spec_version : VERSION . spec_version ,
533+ weight : dispatch_weight,
534+ origin : CallOrigin :: SourceRoot ,
535+ dispatch_fee_payment : DispatchFeePayment :: AtTargetChain ,
536+ call : FromBridgedChainEncodedMessageCall :: new ( call. encode ( ) ) ,
537+ } ) ,
538+ fee : 1 ,
539+ } ,
540+ } ,
541+ ) ;
542+ } ) ;
543+ }
479544}
0 commit comments