tycho_block_util/config/
mod.rs1use anyhow::{Context, Result};
2use tycho_types::error::Error;
3use tycho_types::models::{
4 BlockchainConfig, ConfigParam0, ConfigParam32, ConfigParam33, ConfigParam34, ConfigParam35,
5 ConfigParam36, ConfigParam37, KnownConfigParam,
6};
7use tycho_types::prelude::*;
8
9pub fn compute_gas_price_factor(is_masterchain: bool, gas_price: u64) -> Result<u64> {
10 const fn base_gas_price(is_masterchain: bool) -> u64 {
11 if is_masterchain {
12 10_000 << 16
13 } else {
14 1_000 << 16
15 }
16 }
17
18 let base_gas_price = base_gas_price(is_masterchain);
19 Ok(gas_price.checked_shl(16).context("gas price is too big")? / base_gas_price)
20}
21
22pub const fn apply_price_factor(mut value: u128, price_factor: u64) -> u128 {
23 value = value.saturating_mul(price_factor as u128);
24
25 let r = value & 0xffff != 0;
26 (value >> 16) + r as u128
27}
28
29pub fn build_elections_data_to_sign(
30 election_id: u32,
31 stake_factor: u32,
32 address: &HashBytes,
33 adnl_addr: &HashBytes,
34) -> Vec<u8> {
35 const TL_ID: u32 = 0x654C5074;
36
37 let mut data = Vec::with_capacity(4 + 4 + 4 + 32 + 32);
38 data.extend_from_slice(&TL_ID.to_be_bytes());
39 data.extend_from_slice(&election_id.to_be_bytes());
40 data.extend_from_slice(&stake_factor.to_be_bytes());
41 data.extend_from_slice(address.as_slice());
42 data.extend_from_slice(adnl_addr.as_array());
43 data
44}
45
46pub trait BlockchainConfigExt {
47 fn validate_params(&self) -> Result<()>;
49
50 fn get_prev_validator_set_raw(&self) -> Result<Option<Cell>, Error> {
54 match self.get_raw_cell(ConfigParam33::ID)? {
55 None => self.get_raw_cell(ConfigParam32::ID),
56 set => Ok(set),
57 }
58 }
59
60 fn get_current_validator_set_raw(&self) -> Result<Cell, Error> {
64 match self.get_raw_cell(ConfigParam35::ID)? {
65 None => self.get_raw_cell(ConfigParam34::ID)?,
66 set => set,
67 }
68 .ok_or(Error::CellUnderflow)
69 }
70
71 fn get_next_validator_set_raw(&self) -> Result<Option<Cell>, Error> {
75 match self.get_raw_cell(ConfigParam37::ID)? {
76 None => self.get_raw_cell(ConfigParam36::ID),
77 set => Ok(set),
78 }
79 }
80
81 fn get_raw_cell(&self, id: u32) -> Result<Option<Cell>, Error>;
82}
83
84impl BlockchainConfigExt for BlockchainConfig {
85 fn validate_params(&self) -> Result<()> {
86 let Some(config_address) = self.params.get::<ConfigParam0>()? else {
87 anyhow::bail!("config address is absent");
88 };
89 anyhow::ensure!(config_address == self.address, "config address mismatch");
90
91 let params = self.get_mandatory_params()?;
92 for id in params.keys() {
93 let id = id?;
94 if !self
95 .contains_raw(id)
96 .with_context(|| format!("failed to get config param {id}"))?
97 {
98 anyhow::bail!("mandatory config param {id} is absent");
99 }
100 }
101
102 Ok(())
103 }
104
105 fn get_raw_cell(&self, id: u32) -> Result<Option<Cell>, Error> {
106 let Some(value) = self.params.as_dict().get_raw(id)? else {
107 return Ok(None);
108 };
109 value.get_reference_cloned(0).map(Some)
110 }
111}