1use crate::parameter::Parameter;
2use enum_map::{enum_map, EnumMap};
3use num_rational::Rational32;
4use unc_account_id::AccountType;
5use unc_primitives_core::types::{Balance, Compute, Gas};
6
7#[derive(Debug, serde::Serialize, serde::Deserialize, Clone, Hash, PartialEq, Eq)]
12pub struct Fee {
13 pub send_sir: Gas,
16 pub send_not_sir: Gas,
18 pub execution: Gas,
20}
21
22impl Fee {
23 #[inline]
24 pub fn send_fee(&self, sir: bool) -> Gas {
25 if sir {
26 self.send_sir
27 } else {
28 self.send_not_sir
29 }
30 }
31
32 pub fn exec_fee(&self) -> Gas {
33 self.execution
34 }
35
36 pub fn min_send_and_exec_fee(&self) -> Gas {
38 std::cmp::min(self.send_sir, self.send_not_sir) + self.execution
39 }
40}
41
42#[derive(Debug, Clone, Hash, PartialEq, Eq)]
43pub struct ParameterCost {
44 pub gas: Gas,
45 pub compute: Compute,
46}
47
48#[derive(Debug, Clone, Hash, PartialEq, Eq)]
49pub struct ExtCostsConfig {
50 pub costs: EnumMap<ExtCosts, ParameterCost>,
51}
52
53const SAFETY_MULTIPLIER: u64 = 3;
56
57impl ExtCostsConfig {
58 pub fn gas_cost(&self, param: ExtCosts) -> Gas {
59 self.costs[param].gas
60 }
61
62 pub fn compute_cost(&self, param: ExtCosts) -> Compute {
63 self.costs[param].compute
64 }
65
66 pub fn test_with_undercharging_factor(factor: u64) -> ExtCostsConfig {
69 let costs = enum_map! {
70 ExtCosts::base => SAFETY_MULTIPLIER * 88256037,
71 ExtCosts::contract_loading_base => SAFETY_MULTIPLIER * 11815321,
72 ExtCosts::contract_loading_bytes => SAFETY_MULTIPLIER * 72250,
73 ExtCosts::read_memory_base => SAFETY_MULTIPLIER * 869954400,
74 ExtCosts::read_memory_byte => SAFETY_MULTIPLIER * 1267111,
75 ExtCosts::write_memory_base => SAFETY_MULTIPLIER * 934598287,
76 ExtCosts::write_memory_byte => SAFETY_MULTIPLIER * 907924,
77 ExtCosts::read_register_base => SAFETY_MULTIPLIER * 839055062,
78 ExtCosts::read_register_byte => SAFETY_MULTIPLIER * 32854,
79 ExtCosts::write_register_base => SAFETY_MULTIPLIER * 955174162,
80 ExtCosts::write_register_byte => SAFETY_MULTIPLIER * 1267188,
81 ExtCosts::utf8_decoding_base => SAFETY_MULTIPLIER * 1037259687,
82 ExtCosts::utf8_decoding_byte => SAFETY_MULTIPLIER * 97193493,
83 ExtCosts::utf16_decoding_base => SAFETY_MULTIPLIER * 1181104350,
84 ExtCosts::utf16_decoding_byte => SAFETY_MULTIPLIER * 54525831,
85 ExtCosts::sha256_base => SAFETY_MULTIPLIER * 1513656750,
86 ExtCosts::sha256_byte => SAFETY_MULTIPLIER * 8039117,
87 ExtCosts::keccak256_base => SAFETY_MULTIPLIER * 1959830425,
88 ExtCosts::keccak256_byte => SAFETY_MULTIPLIER * 7157035,
89 ExtCosts::keccak512_base => SAFETY_MULTIPLIER * 1937129412,
90 ExtCosts::keccak512_byte => SAFETY_MULTIPLIER * 12216567,
91 ExtCosts::ripemd160_base => SAFETY_MULTIPLIER * 284558362,
92 ExtCosts::ed25519_verify_base => SAFETY_MULTIPLIER * 1513656750,
93 ExtCosts::ed25519_verify_byte => SAFETY_MULTIPLIER * 7157035,
94 ExtCosts::ripemd160_block => SAFETY_MULTIPLIER * 226702528,
95 ExtCosts::ecrecover_base => SAFETY_MULTIPLIER * 1121789875000,
96 ExtCosts::log_base => SAFETY_MULTIPLIER * 1181104350,
97 ExtCosts::log_byte => SAFETY_MULTIPLIER * 4399597,
98 ExtCosts::storage_write_base => SAFETY_MULTIPLIER * 21398912000,
99 ExtCosts::storage_write_key_byte => SAFETY_MULTIPLIER * 23494289,
100 ExtCosts::storage_write_value_byte => SAFETY_MULTIPLIER * 10339513,
101 ExtCosts::storage_write_evicted_byte => SAFETY_MULTIPLIER * 10705769,
102 ExtCosts::storage_read_base => SAFETY_MULTIPLIER * 18785615250,
103 ExtCosts::storage_read_key_byte => SAFETY_MULTIPLIER * 10317511,
104 ExtCosts::storage_read_value_byte => SAFETY_MULTIPLIER * 1870335,
105 ExtCosts::storage_remove_base => SAFETY_MULTIPLIER * 17824343500,
106 ExtCosts::storage_remove_key_byte => SAFETY_MULTIPLIER * 12740128,
107 ExtCosts::storage_remove_ret_value_byte => SAFETY_MULTIPLIER * 3843852,
108 ExtCosts::storage_has_key_base => SAFETY_MULTIPLIER * 18013298875,
109 ExtCosts::storage_has_key_byte => SAFETY_MULTIPLIER * 10263615,
110 ExtCosts::storage_iter_create_prefix_base => 0,
113 ExtCosts::storage_iter_create_prefix_byte => 0,
114 ExtCosts::storage_iter_create_range_base => 0,
115 ExtCosts::storage_iter_create_from_byte => 0,
116 ExtCosts::storage_iter_create_to_byte => 0,
117 ExtCosts::storage_iter_next_base => 0,
118 ExtCosts::storage_iter_next_key_byte => 0,
119 ExtCosts::storage_iter_next_value_byte => 0,
120 ExtCosts::touching_trie_node => SAFETY_MULTIPLIER * 5367318642,
121 ExtCosts::read_cached_trie_node => SAFETY_MULTIPLIER * 760_000_000,
122 ExtCosts::promise_and_base => SAFETY_MULTIPLIER * 488337800,
123 ExtCosts::promise_and_per_promise => SAFETY_MULTIPLIER * 1817392,
124 ExtCosts::promise_return => SAFETY_MULTIPLIER * 186717462,
125 ExtCosts::validator_pledge_base => SAFETY_MULTIPLIER * 303944908800,
126 ExtCosts::validator_total_pledge_base => SAFETY_MULTIPLIER * 303944908800,
127 ExtCosts::alt_bn128_g1_multiexp_base => 713_000_000_000,
128 ExtCosts::alt_bn128_g1_multiexp_element => 320_000_000_000,
129 ExtCosts::alt_bn128_pairing_check_base => 9_686_000_000_000,
130 ExtCosts::alt_bn128_pairing_check_element => 5_102_000_000_000,
131 ExtCosts::alt_bn128_g1_sum_base => 3_000_000_000,
132 ExtCosts::alt_bn128_g1_sum_element => 5_000_000_000,
133 ExtCosts::validator_power_base => SAFETY_MULTIPLIER * 3_000_000_000,
134 ExtCosts::validator_total_power_base => SAFETY_MULTIPLIER * 3_000_000_000,
135 }
136 .map(|_, value| ParameterCost { gas: value, compute: value * factor });
137 ExtCostsConfig { costs }
138 }
139
140 pub fn test() -> ExtCostsConfig {
142 Self::test_with_undercharging_factor(1)
143 }
144}
145
146#[derive(
151 Copy,
152 Clone,
153 Hash,
154 PartialEq,
155 Eq,
156 Debug,
157 PartialOrd,
158 Ord,
159 strum::Display,
160 strum::EnumIter,
161 enum_map::Enum,
162)]
163#[allow(non_camel_case_types)]
164pub enum ExtCosts {
165 base = 0,
166 contract_loading_base = 1,
167 contract_loading_bytes = 2,
168 read_memory_base = 3,
169 read_memory_byte = 4,
170 write_memory_base = 5,
171 write_memory_byte = 6,
172 read_register_base = 7,
173 read_register_byte = 8,
174 write_register_base = 9,
175 write_register_byte = 10,
176 utf8_decoding_base = 11,
177 utf8_decoding_byte = 12,
178 utf16_decoding_base = 13,
179 utf16_decoding_byte = 14,
180 sha256_base = 15,
181 sha256_byte = 16,
182 keccak256_base = 17,
183 keccak256_byte = 18,
184 keccak512_base = 19,
185 keccak512_byte = 20,
186 ripemd160_base = 21,
187 ripemd160_block = 22,
188 ecrecover_base = 23,
189 log_base = 24,
190 log_byte = 25,
191 storage_write_base = 26,
192 storage_write_key_byte = 27,
193 storage_write_value_byte = 28,
194 storage_write_evicted_byte = 29,
195 storage_read_base = 30,
196 storage_read_key_byte = 31,
197 storage_read_value_byte = 32,
198 storage_remove_base = 33,
199 storage_remove_key_byte = 34,
200 storage_remove_ret_value_byte = 35,
201 storage_has_key_base = 36,
202 storage_has_key_byte = 37,
203 storage_iter_create_prefix_base = 38,
204 storage_iter_create_prefix_byte = 39,
205 storage_iter_create_range_base = 40,
206 storage_iter_create_from_byte = 41,
207 storage_iter_create_to_byte = 42,
208 storage_iter_next_base = 43,
209 storage_iter_next_key_byte = 44,
210 storage_iter_next_value_byte = 45,
211 touching_trie_node = 46,
212 read_cached_trie_node = 47,
213 promise_and_base = 48,
214 promise_and_per_promise = 49,
215 promise_return = 50,
216 validator_pledge_base = 51,
217 validator_total_pledge_base = 52,
218 alt_bn128_g1_multiexp_base = 53,
219 alt_bn128_g1_multiexp_element = 54,
220 alt_bn128_pairing_check_base = 55,
221 alt_bn128_pairing_check_element = 56,
222 alt_bn128_g1_sum_base = 57,
223 alt_bn128_g1_sum_element = 58,
224 ed25519_verify_base = 59,
225 ed25519_verify_byte = 60,
226 validator_power_base = 61,
227 validator_total_power_base = 62,
228}
229
230#[derive(
232 Copy,
233 Clone,
234 Hash,
235 PartialEq,
236 Eq,
237 Debug,
238 PartialOrd,
239 Ord,
240 strum::Display,
241 strum::EnumIter,
242 enum_map::Enum,
243)]
244#[allow(non_camel_case_types)]
245pub enum ActionCosts {
246 create_account = 0,
247 delete_account = 1,
248 deploy_contract_base = 2,
249 deploy_contract_byte = 3,
250 function_call_base = 4,
251 function_call_byte = 5,
252 transfer = 6,
253 pledge = 7,
254 add_full_access_key = 8,
255 add_function_call_key_base = 9,
256 add_function_call_key_byte = 10,
257 delete_key = 11,
258 new_action_receipt = 12,
259 new_data_receipt_base = 13,
260 new_data_receipt_byte = 14,
261 delegate = 15,
262 register_rsa2048_keys = 16,
263 create_rsa2048_challenge = 17,
264}
265
266impl ExtCosts {
267 pub fn gas(self, config: &ExtCostsConfig) -> Gas {
268 config.gas_cost(self)
269 }
270
271 pub fn compute(self, config: &ExtCostsConfig) -> Compute {
272 config.compute_cost(self)
273 }
274
275 pub fn param(&self) -> Parameter {
276 match self {
277 ExtCosts::base => Parameter::WasmBase,
278 ExtCosts::contract_loading_base => Parameter::WasmContractLoadingBase,
279 ExtCosts::contract_loading_bytes => Parameter::WasmContractLoadingBytes,
280 ExtCosts::read_memory_base => Parameter::WasmReadMemoryBase,
281 ExtCosts::read_memory_byte => Parameter::WasmReadMemoryByte,
282 ExtCosts::write_memory_base => Parameter::WasmWriteMemoryBase,
283 ExtCosts::write_memory_byte => Parameter::WasmWriteMemoryByte,
284 ExtCosts::read_register_base => Parameter::WasmReadRegisterBase,
285 ExtCosts::read_register_byte => Parameter::WasmReadRegisterByte,
286 ExtCosts::write_register_base => Parameter::WasmWriteRegisterBase,
287 ExtCosts::write_register_byte => Parameter::WasmWriteRegisterByte,
288 ExtCosts::utf8_decoding_base => Parameter::WasmUtf8DecodingBase,
289 ExtCosts::utf8_decoding_byte => Parameter::WasmUtf8DecodingByte,
290 ExtCosts::utf16_decoding_base => Parameter::WasmUtf16DecodingBase,
291 ExtCosts::utf16_decoding_byte => Parameter::WasmUtf16DecodingByte,
292 ExtCosts::sha256_base => Parameter::WasmSha256Base,
293 ExtCosts::sha256_byte => Parameter::WasmSha256Byte,
294 ExtCosts::keccak256_base => Parameter::WasmKeccak256Base,
295 ExtCosts::keccak256_byte => Parameter::WasmKeccak256Byte,
296 ExtCosts::keccak512_base => Parameter::WasmKeccak512Base,
297 ExtCosts::keccak512_byte => Parameter::WasmKeccak512Byte,
298 ExtCosts::ripemd160_base => Parameter::WasmRipemd160Base,
299 ExtCosts::ripemd160_block => Parameter::WasmRipemd160Block,
300 ExtCosts::ecrecover_base => Parameter::WasmEcrecoverBase,
301 ExtCosts::ed25519_verify_base => Parameter::WasmEd25519VerifyBase,
302 ExtCosts::ed25519_verify_byte => Parameter::WasmEd25519VerifyByte,
303 ExtCosts::log_base => Parameter::WasmLogBase,
304 ExtCosts::log_byte => Parameter::WasmLogByte,
305 ExtCosts::storage_write_base => Parameter::WasmStorageWriteBase,
306 ExtCosts::storage_write_key_byte => Parameter::WasmStorageWriteKeyByte,
307 ExtCosts::storage_write_value_byte => Parameter::WasmStorageWriteValueByte,
308 ExtCosts::storage_write_evicted_byte => Parameter::WasmStorageWriteEvictedByte,
309 ExtCosts::storage_read_base => Parameter::WasmStorageReadBase,
310 ExtCosts::storage_read_key_byte => Parameter::WasmStorageReadKeyByte,
311 ExtCosts::storage_read_value_byte => Parameter::WasmStorageReadValueByte,
312 ExtCosts::storage_remove_base => Parameter::WasmStorageRemoveBase,
313 ExtCosts::storage_remove_key_byte => Parameter::WasmStorageRemoveKeyByte,
314 ExtCosts::storage_remove_ret_value_byte => Parameter::WasmStorageRemoveRetValueByte,
315 ExtCosts::storage_has_key_base => Parameter::WasmStorageHasKeyBase,
316 ExtCosts::storage_has_key_byte => Parameter::WasmStorageHasKeyByte,
317 ExtCosts::storage_iter_create_prefix_base => Parameter::WasmStorageIterCreatePrefixBase,
318 ExtCosts::storage_iter_create_prefix_byte => Parameter::WasmStorageIterCreatePrefixByte,
319 ExtCosts::storage_iter_create_range_base => Parameter::WasmStorageIterCreateRangeBase,
320 ExtCosts::storage_iter_create_from_byte => Parameter::WasmStorageIterCreateFromByte,
321 ExtCosts::storage_iter_create_to_byte => Parameter::WasmStorageIterCreateToByte,
322 ExtCosts::storage_iter_next_base => Parameter::WasmStorageIterNextBase,
323 ExtCosts::storage_iter_next_key_byte => Parameter::WasmStorageIterNextKeyByte,
324 ExtCosts::storage_iter_next_value_byte => Parameter::WasmStorageIterNextValueByte,
325 ExtCosts::touching_trie_node => Parameter::WasmTouchingTrieNode,
326 ExtCosts::read_cached_trie_node => Parameter::WasmReadCachedTrieNode,
327 ExtCosts::promise_and_base => Parameter::WasmPromiseAndBase,
328 ExtCosts::promise_and_per_promise => Parameter::WasmPromiseAndPerPromise,
329 ExtCosts::promise_return => Parameter::WasmPromiseReturn,
330 ExtCosts::validator_pledge_base => Parameter::WasmValidatorPowerBase,
331 ExtCosts::validator_total_pledge_base => Parameter::WasmValidatorTotalPowerBase,
332 ExtCosts::alt_bn128_g1_multiexp_base => Parameter::WasmAltBn128G1MultiexpBase,
333 ExtCosts::alt_bn128_g1_multiexp_element => Parameter::WasmAltBn128G1MultiexpElement,
334 ExtCosts::alt_bn128_pairing_check_base => Parameter::WasmAltBn128PairingCheckBase,
335 ExtCosts::alt_bn128_pairing_check_element => Parameter::WasmAltBn128PairingCheckElement,
336 ExtCosts::alt_bn128_g1_sum_base => Parameter::WasmAltBn128G1SumBase,
337 ExtCosts::alt_bn128_g1_sum_element => Parameter::WasmAltBn128G1SumElement,
338 ExtCosts::validator_power_base => Parameter::WasmValidatorPledgeBase,
339 ExtCosts::validator_total_power_base => Parameter::WasmValidatorTotalPledgeBase,
340 }
341 }
342}
343
344#[derive(Debug, Clone, Hash, PartialEq, Eq)]
345pub struct RuntimeFeesConfig {
346 pub action_fees: EnumMap<ActionCosts, Fee>,
348
349 pub storage_usage_config: StorageUsageConfig,
351
352 pub burnt_gas_reward: Rational32,
354
355 pub pessimistic_gas_price_inflation_ratio: Rational32,
357}
358
359#[derive(Debug, Clone, Hash, PartialEq, Eq)]
361pub struct StorageUsageConfig {
362 pub storage_amount_per_byte: Balance,
365 pub num_bytes_account: u64,
367 pub num_extra_bytes_record: u64,
369}
370
371impl RuntimeFeesConfig {
372 pub fn fee(&self, cost: ActionCosts) -> &Fee {
374 &self.action_fees[cost]
375 }
376
377 pub fn test() -> Self {
378 Self {
379 storage_usage_config: StorageUsageConfig::test(),
380 burnt_gas_reward: Rational32::new(3, 10),
381 pessimistic_gas_price_inflation_ratio: Rational32::new(103, 100),
382 action_fees: enum_map::enum_map! {
383 ActionCosts::create_account => Fee {
384 send_sir: 3_850_000_000_000,
385 send_not_sir: 3_850_000_000_000,
386 execution: 3_850_000_000_000,
387 },
388 ActionCosts::delete_account => Fee {
389 send_sir: 147489000000,
390 send_not_sir: 147489000000,
391 execution: 147489000000,
392 },
393 ActionCosts::deploy_contract_base => Fee {
394 send_sir: 184765750000,
395 send_not_sir: 184765750000,
396 execution: 184765750000,
397 },
398 ActionCosts::deploy_contract_byte => Fee {
399 send_sir: 6812999,
400 send_not_sir: 6812999,
401 execution: 6812999,
402 },
403 ActionCosts::function_call_base => Fee {
404 send_sir: 2319861500000,
405 send_not_sir: 2319861500000,
406 execution: 2319861500000,
407 },
408 ActionCosts::function_call_byte => Fee {
409 send_sir: 2235934,
410 send_not_sir: 2235934,
411 execution: 2235934,
412 },
413 ActionCosts::transfer => Fee {
414 send_sir: 115123062500,
415 send_not_sir: 115123062500,
416 execution: 115123062500,
417 },
418 ActionCosts::pledge => Fee {
419 send_sir: 141715687500,
420 send_not_sir: 141715687500,
421 execution: 102217625000,
422 },
423 ActionCosts::add_full_access_key => Fee {
424 send_sir: 101765125000,
425 send_not_sir: 101765125000,
426 execution: 101765125000,
427 },
428 ActionCosts::add_function_call_key_base => Fee {
429 send_sir: 102217625000,
430 send_not_sir: 102217625000,
431 execution: 102217625000,
432 },
433 ActionCosts::add_function_call_key_byte => Fee {
434 send_sir: 1925331,
435 send_not_sir: 1925331,
436 execution: 1925331,
437 },
438 ActionCosts::delete_key => Fee {
439 send_sir: 94946625000,
440 send_not_sir: 94946625000,
441 execution: 94946625000,
442 },
443 ActionCosts::new_action_receipt => Fee {
444 send_sir: 108059500000,
445 send_not_sir: 108059500000,
446 execution: 108059500000,
447 },
448 ActionCosts::new_data_receipt_base => Fee {
449 send_sir: 4697339419375,
450 send_not_sir: 4697339419375,
451 execution: 4697339419375,
452 },
453 ActionCosts::new_data_receipt_byte => Fee {
454 send_sir: 59357464,
455 send_not_sir: 59357464,
456 execution: 59357464,
457 },
458 ActionCosts::delegate => Fee {
459 send_sir: 200_000_000_000,
460 send_not_sir: 200_000_000_000,
461 execution: 200_000_000_000,
462 },
463 ActionCosts::register_rsa2048_keys => Fee {
464 send_sir: 101765125000,
465 send_not_sir: 101765125000,
466 execution: 101765125000,
467 },
468 ActionCosts::create_rsa2048_challenge => Fee {
469 send_sir: 115123062500,
470 send_not_sir: 115123062500,
471 execution: 115123062500,
472 },
473 },
474 }
475 }
476
477 pub fn free() -> Self {
478 Self {
479 action_fees: enum_map::enum_map! {
480 _ => Fee { send_sir: 0, send_not_sir: 0, execution: 0 }
481 },
482 storage_usage_config: StorageUsageConfig::free(),
483 burnt_gas_reward: Rational32::from_integer(0),
484 pessimistic_gas_price_inflation_ratio: Rational32::from_integer(0),
485 }
486 }
487
488 pub fn min_receipt_with_function_call_gas(&self) -> Gas {
493 self.fee(ActionCosts::new_action_receipt).min_send_and_exec_fee()
494 + self.fee(ActionCosts::function_call_base).min_send_and_exec_fee()
495 }
496}
497
498impl StorageUsageConfig {
499 pub fn test() -> Self {
500 Self {
501 num_bytes_account: 100,
502 num_extra_bytes_record: 40,
503 storage_amount_per_byte: 909 * 100_000_000_000_000_000,
504 }
505 }
506
507 pub(crate) fn free() -> StorageUsageConfig {
508 Self { num_bytes_account: 0, num_extra_bytes_record: 0, storage_amount_per_byte: 0 }
509 }
510}
511
512pub fn transfer_exec_fee(
517 cfg: &RuntimeFeesConfig,
518 implicit_account_creation_allowed: bool,
519 eth_implicit_accounts_enabled: bool,
520 receiver_account_type: AccountType,
521) -> Gas {
522 let transfer_fee = cfg.fee(ActionCosts::transfer).exec_fee();
523 match (implicit_account_creation_allowed, eth_implicit_accounts_enabled, receiver_account_type)
524 {
525 (_, _, AccountType::Reserved) => transfer_fee,
527 (false, _, _) => transfer_fee,
529 (true, false, AccountType::EthAccount) => transfer_fee,
531 (true, true, AccountType::EthAccount) => {
533 transfer_fee + cfg.fee(ActionCosts::create_account).exec_fee()
534 }
535 (true, _, AccountType::UtilityAccount) => {
537 transfer_fee
538 + cfg.fee(ActionCosts::create_account).exec_fee()
539 + cfg.fee(ActionCosts::add_full_access_key).exec_fee()
540 }
541 }
542}
543
544pub fn transfer_send_fee(
545 cfg: &RuntimeFeesConfig,
546 sender_is_receiver: bool,
547 implicit_account_creation_allowed: bool,
548 eth_implicit_accounts_enabled: bool,
549 receiver_account_type: AccountType,
550) -> Gas {
551 let transfer_fee = cfg.fee(ActionCosts::transfer).send_fee(sender_is_receiver);
552 match (implicit_account_creation_allowed, eth_implicit_accounts_enabled, receiver_account_type)
553 {
554 (_, _, AccountType::Reserved) => transfer_fee,
556 (false, _, _) => transfer_fee,
558 (true, false, AccountType::EthAccount) => transfer_fee,
560 (true, true, AccountType::EthAccount) => {
562 transfer_fee + cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver)
563 }
564 (true, _, AccountType::UtilityAccount) => {
566 transfer_fee
567 + cfg.fee(ActionCosts::create_account).send_fee(sender_is_receiver)
568 + cfg.fee(ActionCosts::add_full_access_key).send_fee(sender_is_receiver)
569 }
570 }
571}