1use crate::{
19 limits, metering::Token, weightinfo_extension::OnFinalizeBlockParts, weights::WeightInfo,
20 Config,
21};
22use frame_support::weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight};
23
24const GAS_PER_SECOND: u64 = 40_000_000;
29
30const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND;
34
35#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
36#[derive(Copy, Clone)]
37pub enum RuntimeCosts {
38 HostFn,
40 ExtCodeCopy(u32),
42 CopyFromContract(u32),
44 CopyToContract(u32),
46 CallDataLoad,
48 CallDataCopy(u32),
50 Caller,
52 CallDataSize,
54 ReturnDataSize,
56 ToAccountId,
58 Origin,
60 CodeHash,
62 OwnCodeHash,
64 CodeSize,
66 CallerIsOrigin,
68 CallerIsRoot,
70 Address,
72 RefTimeLeft,
74 WeightLeft,
76 Balance,
78 BalanceOf,
80 ValueTransferred,
82 MinimumBalance,
84 BlockNumber,
86 BlockHash,
88 BlockAuthor,
90 GasPrice,
92 BaseFee,
94 Now,
96 GasLimit,
98 Terminate { code_removed: bool },
100 DepositEvent { num_topic: u32, len: u32 },
102 SetStorage { old_bytes: u32, new_bytes: u32 },
104 ClearStorage(u32),
107 ContainsStorage(u32),
110 GetStorage(u32),
112 TakeStorage(u32),
115 SetTransientStorage { old_bytes: u32, new_bytes: u32 },
117 ClearTransientStorage(u32),
119 ContainsTransientStorage(u32),
121 GetTransientStorage(u32),
123 TakeTransientStorage(u32),
125 CallBase,
127 DelegateCallBase,
129 PrecompileBase,
131 PrecompileWithInfoBase,
133 PrecompileDecode(u32),
135 CallTransferSurcharge { dust_transfer: bool },
138 CallInputCloned(u32),
140 Instantiate { input_data_len: u32, balance_transfer: bool, dust_transfer: bool },
142 Create { init_code_len: u32, balance_transfer: bool, dust_transfer: bool },
144 Ripemd160(u32),
146 HashSha256(u32),
148 HashKeccak256(u32),
150 HashBlake256(u32),
153 HashBlake128(u32),
155 EcdsaRecovery,
157 P256Verify,
159 Sr25519Verify(u32),
161 Precompile(Weight),
163 EcdsaToEthAddress,
165 GetImmutableData(u32),
167 SetImmutableData(u32),
169 Bn128Add,
171 Bn128Mul,
173 Bn128Pairing(u32),
175 Identity(u32),
177 Blake2F(u32),
179 Modexp(u64),
181}
182
183macro_rules! cost_storage {
188 (write_transient, $name:ident $(, $arg:expr )*) => {
189 T::WeightInfo::$name($( $arg ),*)
190 .saturating_add(T::WeightInfo::rollback_transient_storage())
191 .saturating_add(T::WeightInfo::set_transient_storage_full()
192 .saturating_sub(T::WeightInfo::set_transient_storage_empty()))
193 };
194
195 (read_transient, $name:ident $(, $arg:expr )*) => {
196 T::WeightInfo::$name($( $arg ),*)
197 .saturating_add(T::WeightInfo::get_transient_storage_full()
198 .saturating_sub(T::WeightInfo::get_transient_storage_empty()))
199 };
200
201 (write, $name:ident $(, $arg:expr )*) => {
202 T::WeightInfo::$name($( $arg ),*)
203 .saturating_add(T::WeightInfo::set_storage_full()
204 .saturating_sub(T::WeightInfo::set_storage_empty()))
205 };
206
207 (read, $name:ident $(, $arg:expr )*) => {
208 T::WeightInfo::$name($( $arg ),*)
209 .saturating_add(T::WeightInfo::get_storage_full()
210 .saturating_sub(T::WeightInfo::get_storage_empty()))
211 };
212}
213
214macro_rules! cost_args {
215 ($name:ident, $( $arg: expr ),+) => {
217 (T::WeightInfo::$name($( $arg ),+).saturating_sub(cost_args!(@call_zero $name, $( $arg ),+)))
218 };
219 (@call_zero $name:ident, $( $arg:expr ),*) => {
221 T::WeightInfo::$name($( cost_args!(@replace_token $arg) ),*)
222 };
223 (@replace_token $_in:tt) => { 0 };
225}
226
227impl<T: Config> Token<T> for RuntimeCosts {
228 fn influence_lowest_weight_limit(&self) -> bool {
229 true
230 }
231
232 fn weight(&self) -> Weight {
233 use self::RuntimeCosts::*;
234 match *self {
235 HostFn => cost_args!(noop_host_fn, 1),
236 ExtCodeCopy(len) => T::WeightInfo::extcodecopy(len),
237 CopyToContract(len) => T::WeightInfo::seal_copy_to_contract(len),
238 CopyFromContract(len) => T::WeightInfo::seal_return(len),
239 CallDataSize => T::WeightInfo::seal_call_data_size(),
240 ReturnDataSize => T::WeightInfo::seal_return_data_size(),
241 CallDataLoad => T::WeightInfo::seal_call_data_load(),
242 CallDataCopy(len) => T::WeightInfo::seal_call_data_copy(len),
243 Caller => T::WeightInfo::seal_caller(),
244 Origin => T::WeightInfo::seal_origin(),
245 ToAccountId => T::WeightInfo::to_account_id(),
246 CodeHash => T::WeightInfo::seal_code_hash(),
247 CodeSize => T::WeightInfo::seal_code_size(),
248 OwnCodeHash => T::WeightInfo::own_code_hash(),
249 CallerIsOrigin => T::WeightInfo::caller_is_origin(),
250 CallerIsRoot => T::WeightInfo::caller_is_root(),
251 Address => T::WeightInfo::seal_address(),
252 RefTimeLeft => T::WeightInfo::seal_ref_time_left(),
253 WeightLeft => T::WeightInfo::weight_left(),
254 Balance => T::WeightInfo::seal_balance(),
255 BalanceOf => T::WeightInfo::seal_balance_of(),
256 ValueTransferred => T::WeightInfo::seal_value_transferred(),
257 MinimumBalance => T::WeightInfo::minimum_balance(),
258 BlockNumber => T::WeightInfo::seal_block_number(),
259 BlockHash => T::WeightInfo::seal_block_hash(),
260 BlockAuthor => T::WeightInfo::seal_block_author(),
261 GasPrice => T::WeightInfo::seal_gas_price(),
262 BaseFee => T::WeightInfo::seal_base_fee(),
263 Now => T::WeightInfo::seal_now(),
264 GasLimit => T::WeightInfo::seal_gas_limit(),
265 Terminate { code_removed } => {
266 if code_removed {
268 T::WeightInfo::seal_terminate(code_removed.into())
269 .saturating_add(T::WeightInfo::seal_terminate_logic())
270 } else {
271 T::WeightInfo::seal_terminate(code_removed.into())
272 }
273 },
274 DepositEvent { num_topic, len } => T::WeightInfo::seal_deposit_event(num_topic, len)
275 .saturating_add(T::WeightInfo::on_finalize_block_per_event(len))
276 .saturating_add(Weight::from_parts(
277 limits::EXTRA_EVENT_CHARGE_PER_BYTE.saturating_mul(len.into()).into(),
278 0,
279 )),
280 SetStorage { new_bytes, old_bytes } => {
281 cost_storage!(write, seal_set_storage, new_bytes, old_bytes)
282 },
283 ClearStorage(len) => cost_storage!(write, clear_storage, len),
284 ContainsStorage(len) => cost_storage!(read, contains_storage, len),
285 GetStorage(len) => cost_storage!(read, seal_get_storage, len),
286 TakeStorage(len) => cost_storage!(write, take_storage, len),
287 SetTransientStorage { new_bytes, old_bytes } => {
288 cost_storage!(write_transient, seal_set_transient_storage, new_bytes, old_bytes)
289 },
290 ClearTransientStorage(len) => {
291 cost_storage!(write_transient, seal_clear_transient_storage, len)
292 },
293 ContainsTransientStorage(len) => {
294 cost_storage!(read_transient, seal_contains_transient_storage, len)
295 },
296 GetTransientStorage(len) => {
297 cost_storage!(read_transient, seal_get_transient_storage, len)
298 },
299 TakeTransientStorage(len) => {
300 cost_storage!(write_transient, seal_take_transient_storage, len)
301 },
302 CallBase => T::WeightInfo::seal_call(0, 0, 0),
303 DelegateCallBase => T::WeightInfo::seal_delegate_call(),
304 PrecompileBase => T::WeightInfo::seal_call_precompile(0, 0),
305 PrecompileWithInfoBase => T::WeightInfo::seal_call_precompile(1, 0),
306 PrecompileDecode(len) => cost_args!(seal_call_precompile, 0, len),
307 CallTransferSurcharge { dust_transfer } =>
308 cost_args!(seal_call, 1, dust_transfer.into(), 0),
309 CallInputCloned(len) => cost_args!(seal_call, 0, 0, len),
310 Instantiate { input_data_len, balance_transfer, dust_transfer } =>
311 T::WeightInfo::seal_instantiate(
312 balance_transfer.into(),
313 dust_transfer.into(),
314 input_data_len,
315 ),
316 Create { init_code_len, balance_transfer, dust_transfer } =>
317 T::WeightInfo::evm_instantiate(
318 balance_transfer.into(),
319 dust_transfer.into(),
320 init_code_len,
321 ),
322 HashSha256(len) => T::WeightInfo::sha2_256(len),
323 Ripemd160(len) => T::WeightInfo::ripemd_160(len),
324 HashKeccak256(len) => T::WeightInfo::seal_hash_keccak_256(len),
325 HashBlake256(len) => T::WeightInfo::hash_blake2_256(len),
326 HashBlake128(len) => T::WeightInfo::hash_blake2_128(len),
327 EcdsaRecovery => T::WeightInfo::ecdsa_recover(),
328 P256Verify => T::WeightInfo::p256_verify(),
329 Sr25519Verify(len) => T::WeightInfo::seal_sr25519_verify(len),
330 Precompile(weight) => weight,
331 EcdsaToEthAddress => T::WeightInfo::seal_ecdsa_to_eth_address(),
332 GetImmutableData(len) => T::WeightInfo::seal_get_immutable_data(len),
333 SetImmutableData(len) => T::WeightInfo::seal_set_immutable_data(len),
334 Bn128Add => T::WeightInfo::bn128_add(),
335 Bn128Mul => T::WeightInfo::bn128_mul(),
336 Bn128Pairing(len) => T::WeightInfo::bn128_pairing(len),
337 Identity(len) => T::WeightInfo::identity(len),
338 Blake2F(rounds) => T::WeightInfo::blake2f(rounds),
339 Modexp(gas) => Weight::from_parts(gas.saturating_mul(WEIGHT_PER_GAS), 0),
340 }
341 }
342}