diff --git a/substrate/frame/executive/src/lib.rs b/substrate/frame/executive/src/lib.rs index 48ff675f8082d..7d9a352a98dd7 100644 --- a/substrate/frame/executive/src/lib.rs +++ b/substrate/frame/executive/src/lib.rs @@ -152,6 +152,9 @@ use ::{ #[allow(dead_code)] const LOG_TARGET: &str = "runtime::executive"; +/// Maximum nesting level for extrinsics. +pub const MAX_EXTRINSIC_DEPTH: u32 = 256; + pub type CheckedOf = >::Checked; pub type CallOf = as Applyable>::Call; pub type OriginOf = as Dispatchable>::RuntimeOrigin; @@ -627,6 +630,13 @@ where let encoded_len = encoded.len(); sp_tracing::enter_span!(sp_tracing::info_span!("apply_extrinsic", ext=?sp_core::hexdisplay::HexDisplay::from(&encoded))); + + let uxt = ::decode_all_with_depth_limit( + MAX_EXTRINSIC_DEPTH, + &mut &encoded[..], + ) + .expect("Decoding the encoded transaction works; qed"); + // Verify that the signature is good. let xt = uxt.check(&Default::default())?; @@ -703,10 +713,16 @@ where enter_span! { sp_tracing::Level::TRACE, "validate_transaction" }; - let encoded_len = within_span! { sp_tracing::Level::TRACE, "using_encoded"; - uxt.using_encoded(|d| d.len()) + let encoded = within_span! { sp_tracing::Level::TRACE, "using_encoded"; + uxt.encode() }; + let uxt = ::decode_all_with_depth_limit( + MAX_EXTRINSIC_DEPTH, + &mut &encoded[..], + ) + .map_err(|_| InvalidTransaction::Call)?; + let xt = within_span! { sp_tracing::Level::TRACE, "check"; uxt.check(&Default::default()) }?; @@ -721,7 +737,7 @@ where within_span! { sp_tracing::Level::TRACE, "validate"; - xt.validate::(source, &dispatch_info, encoded_len) + xt.validate::(source, &dispatch_info, encoded.len()) } } diff --git a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs index 652c6fca39c6c..78b277b7cbd29 100644 --- a/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs +++ b/substrate/primitives/api/proc-macro/src/impl_runtime_apis.rs @@ -103,8 +103,7 @@ fn generate_impl_call( quote!( #let_binding = - match #c::DecodeLimit::decode_all_with_depth_limit( - #c::MAX_EXTRINSIC_DEPTH, + match #c::Decode::decode( &mut #input, ) { Ok(res) => res,