Skip to content

Commit

Permalink
Disable total pov size check for mandatory extrinsics
Browse files Browse the repository at this point in the history
  • Loading branch information
skunert committed May 24, 2024
1 parent f469fbf commit e4b89cc
Showing 1 changed file with 108 additions and 18 deletions.
126 changes: 108 additions & 18 deletions substrate/frame/system/src/extensions/check_weight.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

use crate::{limits::BlockWeights, Config, Pallet, LOG_TARGET};
use crate::{limits::BlockWeights, Config, DispatchClass, Pallet, LOG_TARGET};
use codec::{Decode, Encode};
use frame_support::{
dispatch::{DispatchInfo, PostDispatchInfo},
Expand Down Expand Up @@ -107,7 +107,7 @@ where
let maximum_weight = T::BlockWeights::get();
let next_weight =
calculate_consumed_weight::<T::RuntimeCall>(&maximum_weight, all_weight, info)?;
check_combined_proof_size(&maximum_weight, next_len, &next_weight)?;
check_combined_proof_size::<T::RuntimeCall>(info, &maximum_weight, next_len, &next_weight)?;
Self::check_extrinsic_weight(info)?;

crate::AllExtrinsicsLen::<T>::put(next_len);
Expand All @@ -131,11 +131,20 @@ where
}

/// Check that the combined extrinsic length and proof size together do not exceed the PoV limit.
pub fn check_combined_proof_size(
pub fn check_combined_proof_size<Call>(
info: &DispatchInfoOf<Call>,
maximum_weight: &BlockWeights,
next_len: u32,
next_weight: &crate::ConsumedWeight,
) -> Result<(), TransactionValidityError> {
) -> Result<(), TransactionValidityError>
where
Call: Dispatchable<Info = DispatchInfo, PostInfo = PostDispatchInfo>,
{
if matches!(info.class, DispatchClass::Mandatory) {
// Allow mandatory extrinsics
return Ok(());
}

// This extra check ensures that the extrinsic length does not push the
// PoV over the limit.
let total_pov_size = next_weight.total().proof_size().saturating_add(next_len as u64);
Expand All @@ -146,7 +155,7 @@ pub fn check_combined_proof_size(
total_pov_size as f64/1024.0,
maximum_weight.max_block.proof_size() as f64/1024.0
);
return Err(InvalidTransaction::ExhaustsResources.into())
return Err(InvalidTransaction::ExhaustsResources.into());
}
Ok(())
}
Expand Down Expand Up @@ -190,7 +199,7 @@ where
"Exceeded the per-class allowance.",
);

return Err(InvalidTransaction::ExhaustsResources.into())
return Err(InvalidTransaction::ExhaustsResources.into());
},
// There is no `max_total` limit (`None`),
// or we are below the limit.
Expand All @@ -208,7 +217,7 @@ where
"Total block weight is exceeded.",
);

return Err(InvalidTransaction::ExhaustsResources.into())
return Err(InvalidTransaction::ExhaustsResources.into());
},
// There is either no limit in reserved pool (`None`),
// or we are below the limit.
Expand Down Expand Up @@ -791,6 +800,8 @@ mod tests {

assert_eq!(maximum_weight.max_block, Weight::from_parts(20, 10));

let info = DispatchInfo { class: DispatchClass::Normal, ..Default::default() };
let mandatory = DispatchInfo { class: DispatchClass::Mandatory, ..Default::default() };
// We have 10 reftime and 5 proof size left over.
let next_weight = crate::ConsumedWeight::new(|class| match class {
DispatchClass::Normal => Weight::from_parts(10, 5),
Expand All @@ -799,24 +810,61 @@ mod tests {
});

// Simple checks for the length
assert_ok!(check_combined_proof_size(&maximum_weight, 0, &next_weight));
assert_ok!(check_combined_proof_size(&maximum_weight, 5, &next_weight));
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
0,
&next_weight
));
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
5,
&next_weight
));
assert_err!(
check_combined_proof_size(&maximum_weight, 6, &next_weight),
check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
6,
&next_weight
),
InvalidTransaction::ExhaustsResources
);
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&mandatory,
&maximum_weight,
6,
&next_weight
));

// We have 10 reftime and 0 proof size left over.
let next_weight = crate::ConsumedWeight::new(|class| match class {
DispatchClass::Normal => Weight::from_parts(10, 10),
DispatchClass::Operational => Weight::from_parts(0, 0),
DispatchClass::Mandatory => Weight::zero(),
});
assert_ok!(check_combined_proof_size(&maximum_weight, 0, &next_weight));
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
0,
&next_weight
));
assert_err!(
check_combined_proof_size(&maximum_weight, 1, &next_weight),
check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
1,
&next_weight
),
InvalidTransaction::ExhaustsResources
);
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&mandatory,
&maximum_weight,
1,
&next_weight
));

// We have 10 reftime and 2 proof size left over.
// Used weight is spread across dispatch classes this time.
Expand All @@ -825,12 +873,33 @@ mod tests {
DispatchClass::Operational => Weight::from_parts(0, 3),
DispatchClass::Mandatory => Weight::zero(),
});
assert_ok!(check_combined_proof_size(&maximum_weight, 0, &next_weight));
assert_ok!(check_combined_proof_size(&maximum_weight, 2, &next_weight));
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
0,
&next_weight
));
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
2,
&next_weight
));
assert_err!(
check_combined_proof_size(&maximum_weight, 3, &next_weight),
check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
3,
&next_weight
),
InvalidTransaction::ExhaustsResources
);
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&mandatory,
&maximum_weight,
3,
&next_weight
));

// Ref time is over the limit. Should not happen, but we should make sure that it is
// ignored.
Expand All @@ -839,11 +908,32 @@ mod tests {
DispatchClass::Operational => Weight::from_parts(0, 0),
DispatchClass::Mandatory => Weight::zero(),
});
assert_ok!(check_combined_proof_size(&maximum_weight, 0, &next_weight));
assert_ok!(check_combined_proof_size(&maximum_weight, 5, &next_weight));
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
0,
&next_weight
));
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
5,
&next_weight
));
assert_err!(
check_combined_proof_size(&maximum_weight, 6, &next_weight),
check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&info,
&maximum_weight,
6,
&next_weight
),
InvalidTransaction::ExhaustsResources
);
assert_ok!(check_combined_proof_size::<<Test as Config>::RuntimeCall>(
&mandatory,
&maximum_weight,
6,
&next_weight
));
}
}

0 comments on commit e4b89cc

Please sign in to comment.