1use crate::{
19 Config, limits, metering::Token, weightinfo_extension::OnFinalizeBlockParts,
20 weights::WeightInfo,
21};
22use frame_support::weights::{Weight, constants::WEIGHT_REF_TIME_PER_SECOND};
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 },
310 CallInputCloned(len) => cost_args!(seal_call, 0, 0, len),
311 Instantiate { input_data_len, balance_transfer, dust_transfer } => {
312 T::WeightInfo::seal_instantiate(
313 balance_transfer.into(),
314 dust_transfer.into(),
315 input_data_len,
316 )
317 },
318 Create { init_code_len, balance_transfer, dust_transfer } => {
319 T::WeightInfo::evm_instantiate(
320 balance_transfer.into(),
321 dust_transfer.into(),
322 init_code_len,
323 )
324 },
325 HashSha256(len) => T::WeightInfo::sha2_256(len),
326 Ripemd160(len) => T::WeightInfo::ripemd_160(len),
327 HashKeccak256(len) => T::WeightInfo::seal_hash_keccak_256(len),
328 HashBlake256(len) => T::WeightInfo::hash_blake2_256(len),
329 HashBlake128(len) => T::WeightInfo::hash_blake2_128(len),
330 EcdsaRecovery => T::WeightInfo::ecdsa_recover(),
331 P256Verify => T::WeightInfo::p256_verify(),
332 Sr25519Verify(len) => T::WeightInfo::seal_sr25519_verify(len),
333 Precompile(weight) => weight,
334 EcdsaToEthAddress => T::WeightInfo::seal_ecdsa_to_eth_address(),
335 GetImmutableData(len) => T::WeightInfo::seal_get_immutable_data(len),
336 SetImmutableData(len) => T::WeightInfo::seal_set_immutable_data(len),
337 Bn128Add => T::WeightInfo::bn128_add(),
338 Bn128Mul => T::WeightInfo::bn128_mul(),
339 Bn128Pairing(len) => T::WeightInfo::bn128_pairing(len),
340 Identity(len) => T::WeightInfo::identity(len),
341 Blake2F(rounds) => T::WeightInfo::blake2f(rounds),
342 Modexp(gas) => Weight::from_parts(gas.saturating_mul(WEIGHT_PER_GAS), 0),
343 }
344 }
345}