Newer
Older
/// Base gas cost to call into a contract.
pub call_base_cost: Gas,
/// Base gas cost to instantiate a contract.
pub instantiate_base_cost: Gas,
/// Gas cost per one byte read from the sandbox memory.
/// Gas cost per one byte written to the sandbox memory.
/// Cost for a simple balance transfer.
pub transfer_cost: Gas,
/// The maximum number of topics supported by an event.
pub max_event_topics: u32,
///
/// See https://wiki.parity.io/WebAssembly-StackHeight to find out
/// how the stack frame cost is calculated.
pub max_stack_height: u32,
/// Maximum number of memory pages allowed for a contract.
/// Maximum allowed size of a declared table.
pub max_table_size: u32,
/// Whether the `ext_println` function is allowed to be used contracts.
/// MUST only be enabled for `dev` chains, NOT for production chains
pub enable_println: bool,
/// The maximum length of a subject used for PRNG generation.
pub max_subject_len: u32,
impl Default for Schedule {
fn default() -> Schedule {
put_code_per_byte_cost: 1,
grow_mem_cost: 1,
regular_op_cost: 1,
return_data_per_byte_cost: 1,
event_data_per_byte_cost: 1,
event_per_topic_cost: 1,
event_base_cost: 1,
call_base_cost: 135,
instantiate_base_cost: 175,
sandbox_data_read_cost: 1,
sandbox_data_write_cost: 1,
max_stack_height: 64 * 1024,
max_memory_pages: 16,
max_table_size: 16 * 1024,
enable_println: false,
/// `SignedExtension` that checks if a transaction would exhausts the block gas limit.
#[derive(Encode, Decode, Clone, Eq, PartialEq)]
pub struct CheckBlockGasLimit<T: Trait + Send + Sync>(PhantomData<T>);
impl<T: Trait + Send + Sync> Default for CheckBlockGasLimit<T> {
fn default() -> Self {
Self(PhantomData)
}
}
impl<T: Trait + Send + Sync> sp_std::fmt::Debug for CheckBlockGasLimit<T> {
fn fmt(&self, f: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
write!(f, "CheckBlockGasLimit")
}
#[cfg(not(feature = "std"))]
fn fmt(&self, _: &mut sp_std::fmt::Formatter) -> sp_std::fmt::Result {
Ok(())
}
}
impl<T: Trait + Send + Sync> SignedExtension for CheckBlockGasLimit<T> {
const IDENTIFIER: &'static str = "CheckBlockGasLimit";
type AccountId = T::AccountId;
type Call = <T as Trait>::Call;
type AdditionalSigned = ();
type DispatchInfo = DispatchInfo;
fn additional_signed(&self) -> sp_std::result::Result<(), TransactionValidityError> { Ok(()) }
fn validate(
&self,
_: &Self::AccountId,
call: &Self::Call,
_: Self::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"),
}
}
}