1use crate::{gas::Token, weights::WeightInfo, Config};
19use frame_support::weights::{constants::WEIGHT_REF_TIME_PER_SECOND, Weight};
20
21const GAS_PER_SECOND: u64 = 40_000_000;
26
27const WEIGHT_PER_GAS: u64 = WEIGHT_REF_TIME_PER_SECOND / GAS_PER_SECOND;
31
32#[cfg_attr(test, derive(Debug, PartialEq, Eq))]
33#[derive(Copy, Clone)]
34pub enum RuntimeCosts {
35 HostFn,
37 ExtCodeCopy(u32),
39 CopyFromContract(u32),
41 CopyToContract(u32),
43 CallDataLoad,
45 CallDataCopy(u32),
47 Caller,
49 CallDataSize,
51 ReturnDataSize,
53 ToAccountId,
55 Origin,
57 CodeHash,
59 OwnCodeHash,
61 CodeSize,
63 CallerIsOrigin,
65 CallerIsRoot,
67 Address,
69 RefTimeLeft,
71 WeightLeft,
73 Balance,
75 BalanceOf,
77 ValueTransferred,
79 MinimumBalance,
81 BlockNumber,
83 BlockHash,
85 BlockAuthor,
87 GasPrice,
89 BaseFee,
91 Now,
93 GasLimit,
95 WeightToFee,
97 Terminate { code_removed: bool },
99 DepositEvent { num_topic: u32, len: u32 },
101 SetStorage { old_bytes: u32, new_bytes: u32 },
103 ClearStorage(u32),
105 ContainsStorage(u32),
107 GetStorage(u32),
109 TakeStorage(u32),
111 SetTransientStorage { old_bytes: u32, new_bytes: u32 },
113 ClearTransientStorage(u32),
115 ContainsTransientStorage(u32),
117 GetTransientStorage(u32),
119 TakeTransientStorage(u32),
121 CallBase,
123 DelegateCallBase,
125 PrecompileBase,
127 PrecompileWithInfoBase,
129 PrecompileDecode(u32),
131 CallTransferSurcharge { dust_transfer: bool },
134 CallInputCloned(u32),
136 Instantiate { input_data_len: u32, balance_transfer: bool, dust_transfer: bool },
138 Ripemd160(u32),
140 HashSha256(u32),
142 HashKeccak256(u32),
144 HashBlake256(u32),
147 HashBlake128(u32),
149 EcdsaRecovery,
151 Sr25519Verify(u32),
153 Precompile(Weight),
155 SetCodeHash { old_code_removed: bool },
157 EcdsaToEthAddress,
159 GetImmutableData(u32),
161 SetImmutableData(u32),
163 Bn128Add,
165 Bn128Mul,
167 Bn128Pairing(u32),
169 Identity(u32),
171 Blake2F(u32),
173 Modexp(u64),
175}
176
177macro_rules! cost_storage {
182 (write_transient, $name:ident $(, $arg:expr )*) => {
183 T::WeightInfo::$name($( $arg ),*)
184 .saturating_add(T::WeightInfo::rollback_transient_storage())
185 .saturating_add(T::WeightInfo::set_transient_storage_full()
186 .saturating_sub(T::WeightInfo::set_transient_storage_empty()))
187 };
188
189 (read_transient, $name:ident $(, $arg:expr )*) => {
190 T::WeightInfo::$name($( $arg ),*)
191 .saturating_add(T::WeightInfo::get_transient_storage_full()
192 .saturating_sub(T::WeightInfo::get_transient_storage_empty()))
193 };
194
195 (write, $name:ident $(, $arg:expr )*) => {
196 T::WeightInfo::$name($( $arg ),*)
197 .saturating_add(T::WeightInfo::set_storage_full()
198 .saturating_sub(T::WeightInfo::set_storage_empty()))
199 };
200
201 (read, $name:ident $(, $arg:expr )*) => {
202 T::WeightInfo::$name($( $arg ),*)
203 .saturating_add(T::WeightInfo::get_storage_full()
204 .saturating_sub(T::WeightInfo::get_storage_empty()))
205 };
206}
207
208macro_rules! cost_args {
209 ($name:ident, $( $arg: expr ),+) => {
211 (T::WeightInfo::$name($( $arg ),+).saturating_sub(cost_args!(@call_zero $name, $( $arg ),+)))
212 };
213 (@call_zero $name:ident, $( $arg:expr ),*) => {
215 T::WeightInfo::$name($( cost_args!(@replace_token $arg) ),*)
216 };
217 (@replace_token $_in:tt) => { 0 };
219}
220
221impl<T: Config> Token<T> for RuntimeCosts {
222 fn influence_lowest_gas_limit(&self) -> bool {
223 true
224 }
225
226 fn weight(&self) -> Weight {
227 use self::RuntimeCosts::*;
228 match *self {
229 HostFn => cost_args!(noop_host_fn, 1),
230 ExtCodeCopy(len) => T::WeightInfo::extcodecopy(len),
231 CopyToContract(len) => T::WeightInfo::seal_copy_to_contract(len),
232 CopyFromContract(len) => T::WeightInfo::seal_return(len),
233 CallDataSize => T::WeightInfo::seal_call_data_size(),
234 ReturnDataSize => T::WeightInfo::seal_return_data_size(),
235 CallDataLoad => T::WeightInfo::seal_call_data_load(),
236 CallDataCopy(len) => T::WeightInfo::seal_call_data_copy(len),
237 Caller => T::WeightInfo::seal_caller(),
238 Origin => T::WeightInfo::seal_origin(),
239 ToAccountId => T::WeightInfo::to_account_id(),
240 CodeHash => T::WeightInfo::seal_code_hash(),
241 CodeSize => T::WeightInfo::seal_code_size(),
242 OwnCodeHash => T::WeightInfo::own_code_hash(),
243 CallerIsOrigin => T::WeightInfo::caller_is_origin(),
244 CallerIsRoot => T::WeightInfo::caller_is_root(),
245 Address => T::WeightInfo::seal_address(),
246 RefTimeLeft => T::WeightInfo::seal_ref_time_left(),
247 WeightLeft => T::WeightInfo::weight_left(),
248 Balance => T::WeightInfo::seal_balance(),
249 BalanceOf => T::WeightInfo::seal_balance_of(),
250 ValueTransferred => T::WeightInfo::seal_value_transferred(),
251 MinimumBalance => T::WeightInfo::minimum_balance(),
252 BlockNumber => T::WeightInfo::seal_block_number(),
253 BlockHash => T::WeightInfo::seal_block_hash(),
254 BlockAuthor => T::WeightInfo::seal_block_author(),
255 GasPrice => T::WeightInfo::seal_gas_price(),
256 BaseFee => T::WeightInfo::seal_base_fee(),
257 Now => T::WeightInfo::seal_now(),
258 GasLimit => T::WeightInfo::seal_gas_limit(),
259 WeightToFee => T::WeightInfo::seal_weight_to_fee(),
260 Terminate { code_removed } => T::WeightInfo::seal_terminate(code_removed.into()),
261 DepositEvent { num_topic, len } => T::WeightInfo::seal_deposit_event(num_topic, len),
262 SetStorage { new_bytes, old_bytes } => {
263 cost_storage!(write, seal_set_storage, new_bytes, old_bytes)
264 },
265 ClearStorage(len) => cost_storage!(write, seal_clear_storage, len),
266 ContainsStorage(len) => cost_storage!(read, seal_contains_storage, len),
267 GetStorage(len) => cost_storage!(read, seal_get_storage, len),
268 TakeStorage(len) => cost_storage!(write, seal_take_storage, len),
269 SetTransientStorage { new_bytes, old_bytes } => {
270 cost_storage!(write_transient, seal_set_transient_storage, new_bytes, old_bytes)
271 },
272 ClearTransientStorage(len) => {
273 cost_storage!(write_transient, seal_clear_transient_storage, len)
274 },
275 ContainsTransientStorage(len) => {
276 cost_storage!(read_transient, seal_contains_transient_storage, len)
277 },
278 GetTransientStorage(len) => {
279 cost_storage!(read_transient, seal_get_transient_storage, len)
280 },
281 TakeTransientStorage(len) => {
282 cost_storage!(write_transient, seal_take_transient_storage, len)
283 },
284 CallBase => T::WeightInfo::seal_call(0, 0, 0),
285 DelegateCallBase => T::WeightInfo::seal_delegate_call(),
286 PrecompileBase => T::WeightInfo::seal_call_precompile(0, 0),
287 PrecompileWithInfoBase => T::WeightInfo::seal_call_precompile(1, 0),
288 PrecompileDecode(len) => cost_args!(seal_call_precompile, 0, len),
289 CallTransferSurcharge { dust_transfer } =>
290 cost_args!(seal_call, 1, dust_transfer.into(), 0),
291 CallInputCloned(len) => cost_args!(seal_call, 0, 0, len),
292 Instantiate { input_data_len, balance_transfer, dust_transfer } =>
293 T::WeightInfo::seal_instantiate(
294 input_data_len,
295 balance_transfer.into(),
296 dust_transfer.into(),
297 ),
298 HashSha256(len) => T::WeightInfo::sha2_256(len),
299 Ripemd160(len) => T::WeightInfo::ripemd_160(len),
300 HashKeccak256(len) => T::WeightInfo::seal_hash_keccak_256(len),
301 HashBlake256(len) => T::WeightInfo::hash_blake2_256(len),
302 HashBlake128(len) => T::WeightInfo::hash_blake2_128(len),
303 EcdsaRecovery => T::WeightInfo::ecdsa_recover(),
304 Sr25519Verify(len) => T::WeightInfo::seal_sr25519_verify(len),
305 Precompile(weight) => weight,
306 SetCodeHash { old_code_removed } =>
307 T::WeightInfo::seal_set_code_hash(old_code_removed.into()),
308 EcdsaToEthAddress => T::WeightInfo::seal_ecdsa_to_eth_address(),
309 GetImmutableData(len) => T::WeightInfo::seal_get_immutable_data(len),
310 SetImmutableData(len) => T::WeightInfo::seal_set_immutable_data(len),
311 Bn128Add => T::WeightInfo::bn128_add(),
312 Bn128Mul => T::WeightInfo::bn128_mul(),
313 Bn128Pairing(len) => T::WeightInfo::bn128_pairing(len),
314 Identity(len) => T::WeightInfo::identity(len),
315 Blake2F(rounds) => T::WeightInfo::blake2f(rounds),
316 Modexp(gas) => Weight::from_parts(gas.saturating_mul(WEIGHT_PER_GAS), 0),
317 }
318 }
319}