lib.rs 35.9 KiB
Newer Older
}

impl<T: Trait + Send + Sync> SignedExtension for CheckBlockGasLimit<T> {
	type AccountId = T::AccountId;
	type Call = <T as Trait>::Call;
	type AdditionalSigned = ();
	type Pre = ();

	fn additional_signed(&self) -> rstd::result::Result<(), TransactionValidityError> { Ok(()) }

	fn validate(
		&self,
		_: &Self::AccountId,
		call: &Self::Call,
		_: DispatchInfo,
		_: usize,
	) -> TransactionValidity {
		let call = match call.is_sub_type() {
			Some(call) => call,
			None => return Ok(ValidTransaction::default()),
		};

		match call {
			Call::claim_surcharge(_, _) | Call::update_schedule(_) =>
				Ok(ValidTransaction::default()),
			Call::put_code(gas_limit, _)
				| Call::call(_, _, gas_limit, _)
				| Call::instantiate(_, gas_limit, _, _)
			=> {
				// Check if the specified amount of gas is available in the current block.
				// This cannot underflow since `gas_spent` is never greater than `T::BlockGasLimit`.
				let gas_available = T::BlockGasLimit::get() - <Module<T>>::gas_spent();
				if *gas_limit > gas_available {
					// gas limit reached, revert the transaction and retry again in the future
					InvalidTransaction::ExhaustsResources.into()
				} else {
					Ok(ValidTransaction::default())
				}
			},
			Call::__PhantomItem(_, _)  => unreachable!("Variant is never constructed"),
		}
	}
}