precompile_utils/evm/
costs.rs
1use crate::EvmResult;
23use fp_evm::{ExitError, PrecompileFailure};
24use sp_core::U256;
25
26pub fn log_costs(topics: usize, data_len: usize) -> EvmResult<u64> {
27 const G_LOG: u64 = 375;
31 const G_LOGDATA: u64 = 8;
32 const G_LOGTOPIC: u64 = 375;
33
34 let topic_cost = G_LOGTOPIC
35 .checked_mul(topics as u64)
36 .ok_or(PrecompileFailure::Error {
37 exit_status: ExitError::OutOfGas,
38 })?;
39
40 let data_cost = G_LOGDATA
41 .checked_mul(data_len as u64)
42 .ok_or(PrecompileFailure::Error {
43 exit_status: ExitError::OutOfGas,
44 })?;
45
46 G_LOG
47 .checked_add(topic_cost)
48 .ok_or(PrecompileFailure::Error {
49 exit_status: ExitError::OutOfGas,
50 })?
51 .checked_add(data_cost)
52 .ok_or(PrecompileFailure::Error {
53 exit_status: ExitError::OutOfGas,
54 })
55}
56
57pub fn call_cost(value: U256, config: &evm::Config) -> u64 {
60 pub const G_CALLVALUE: u64 = 9000;
62 pub const G_NEWACCOUNT: u64 = 25000;
63
64 fn address_access_cost(is_cold: bool, regular_value: u64, config: &evm::Config) -> u64 {
65 if config.increase_state_access_gas {
66 if is_cold {
67 config.gas_account_access_cold
68 } else {
69 config.gas_storage_read_warm
70 }
71 } else {
72 regular_value
73 }
74 }
75
76 fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 {
77 if is_call_or_callcode && transfers_value {
78 G_CALLVALUE
79 } else {
80 0
81 }
82 }
83
84 fn new_cost(
85 is_call_or_staticcall: bool,
86 new_account: bool,
87 transfers_value: bool,
88 config: &evm::Config,
89 ) -> u64 {
90 let eip161 = !config.empty_considered_exists;
91 if is_call_or_staticcall {
92 if eip161 {
93 if transfers_value && new_account {
94 G_NEWACCOUNT
95 } else {
96 0
97 }
98 } else if new_account {
99 G_NEWACCOUNT
100 } else {
101 0
102 }
103 } else {
104 0
105 }
106 }
107
108 let transfers_value = value != U256::default();
109 let is_cold = true;
110 let is_call_or_callcode = true;
111 let is_call_or_staticcall = true;
112 let new_account = true;
113
114 address_access_cost(is_cold, config.gas_call, config)
115 + xfer_cost(is_call_or_callcode, transfers_value)
116 + new_cost(is_call_or_staticcall, new_account, transfers_value, config)
117}