1use crate::cell::*;
4use crate::dict::{Dict, DictKey};
5use crate::error::Error;
6use crate::num::Tokens;
7
8use crate::models::currency::ExtraCurrencyCollection;
9use crate::models::global_version::GlobalVersion;
10
11pub use self::params::*;
12
13mod params;
14
15#[cfg(test)]
16mod tests;
17
18#[derive(Debug, Clone, Eq, PartialEq, Store, Load)]
20#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
21pub struct BlockchainConfig {
22 pub address: HashBytes,
24 pub params: BlockchainConfigParams,
26}
27
28impl BlockchainConfig {
29 pub fn new_empty(address: HashBytes) -> Self {
31 let mut params = BlockchainConfigParams(Dict::new());
32 params
33 .set_raw(ConfigParam0::ID, CellBuilder::build_from(address).unwrap())
34 .unwrap();
35
36 Self { address, params }
37 }
38}
39
40impl std::ops::Deref for BlockchainConfig {
41 type Target = BlockchainConfigParams;
42
43 #[inline]
44 fn deref(&self) -> &Self::Target {
45 &self.params
46 }
47}
48
49impl std::ops::DerefMut for BlockchainConfig {
50 #[inline]
51 fn deref_mut(&mut self) -> &mut Self::Target {
52 &mut self.params
53 }
54}
55
56#[derive(Debug, Clone, Eq, PartialEq)]
58#[repr(transparent)]
59pub struct BlockchainConfigParams(Dict<u32, Cell>);
60
61impl BlockchainConfigParams {
62 pub fn get_elector_address(&self) -> Result<HashBytes, Error> {
66 ok!(self.get::<ConfigParam1>()).ok_or(Error::CellUnderflow)
67 }
68
69 pub fn set_elector_address(&mut self, address: &HashBytes) -> Result<bool, Error> {
73 self.set_raw(ConfigParam1::ID, ok!(CellBuilder::build_from(address)))
74 }
75
76 pub fn get_minter_address(&self) -> Result<HashBytes, Error> {
80 match ok!(self.get::<ConfigParam2>()) {
81 Some(address) => Ok(address),
82 None => ok!(self.get::<ConfigParam0>()).ok_or(Error::CellUnderflow),
83 }
84 }
85
86 pub fn set_minter_address(&mut self, address: &HashBytes) -> Result<bool, Error> {
90 self.set_raw(ConfigParam2::ID, ok!(CellBuilder::build_from(address)))
91 }
92
93 pub fn get_fee_collector_address(&self) -> Result<HashBytes, Error> {
97 match ok!(self.get::<ConfigParam3>()) {
98 Some(address) => Ok(address),
99 None => ok!(self.get::<ConfigParam1>()).ok_or(Error::CellUnderflow),
100 }
101 }
102
103 pub fn set_fee_collector_address(&mut self, address: &HashBytes) -> Result<bool, Error> {
107 self.set_raw(ConfigParam3::ID, ok!(CellBuilder::build_from(address)))
108 }
109
110 pub fn get_global_version(&self) -> Result<GlobalVersion, Error> {
114 ok!(self.get::<ConfigParam8>()).ok_or(Error::CellUnderflow)
115 }
116
117 pub fn set_global_version(&mut self, version: &GlobalVersion) -> Result<bool, Error> {
121 self.set_raw(ConfigParam8::ID, ok!(CellBuilder::build_from(version)))
122 }
123
124 pub fn get_mandatory_params(&self) -> Result<Dict<u32, ()>, Error> {
128 ok!(self.get::<ConfigParam9>()).ok_or(Error::CellUnderflow)
129 }
130
131 pub fn set_mandatory_params(&mut self, params: &[u32]) -> Result<bool, Error> {
135 let mut dict = Dict::new();
136 for id in params {
137 ok!(dict.set(*id, ()));
138 }
139 self.set_raw(
140 ConfigParam9::ID,
141 ok!(CellBuilder::build_from(NonEmptyDict(dict))),
142 )
143 }
144
145 pub fn get_critical_params(&self) -> Result<Dict<u32, ()>, Error> {
149 ok!(self.get::<ConfigParam10>()).ok_or(Error::CellUnderflow)
150 }
151
152 pub fn set_critical_params(&mut self, params: &[u32]) -> Result<bool, Error> {
156 let mut dict = Dict::new();
157 for id in params {
158 ok!(dict.set(*id, ()));
159 }
160 self.set_raw(
161 ConfigParam10::ID,
162 ok!(CellBuilder::build_from(NonEmptyDict(dict))),
163 )
164 }
165
166 pub fn get_workchains(&self) -> Result<Dict<i32, WorkchainDescription>, Error> {
170 ok!(self.get::<ConfigParam12>()).ok_or(Error::CellUnderflow)
171 }
172
173 pub fn set_workchains(
177 &mut self,
178 workchains: &Dict<i32, WorkchainDescription>,
179 ) -> Result<bool, Error> {
180 self.set_raw(ConfigParam12::ID, ok!(CellBuilder::build_from(workchains)))
181 }
182
183 pub fn get_block_creation_reward(&self, masterchain: bool) -> Result<Tokens, Error> {
187 let rewards = ok!(self.get_block_creation_rewards());
188 Ok(if masterchain {
189 rewards.masterchain_block_fee
190 } else {
191 rewards.basechain_block_fee
192 })
193 }
194
195 pub fn get_block_creation_rewards(&self) -> Result<BlockCreationRewards, Error> {
199 ok!(self.get::<ConfigParam14>()).ok_or(Error::CellUnderflow)
200 }
201
202 pub fn set_block_creation_rewards(
206 &mut self,
207 rewards: &BlockCreationRewards,
208 ) -> Result<bool, Error> {
209 self.set_raw(ConfigParam14::ID, ok!(CellBuilder::build_from(rewards)))
210 }
211
212 pub fn get_election_timings(&self) -> Result<ElectionTimings, Error> {
216 ok!(self.get::<ConfigParam15>()).ok_or(Error::CellUnderflow)
217 }
218
219 pub fn set_election_timings(&mut self, timings: &ElectionTimings) -> Result<bool, Error> {
223 self.set_raw(ConfigParam15::ID, ok!(CellBuilder::build_from(timings)))
224 }
225
226 pub fn get_validator_count_params(&self) -> Result<ValidatorCountParams, Error> {
230 ok!(self.get::<ConfigParam16>()).ok_or(Error::CellUnderflow)
231 }
232
233 pub fn set_validator_count_params(
237 &mut self,
238 params: &ValidatorCountParams,
239 ) -> Result<bool, Error> {
240 self.set_raw(ConfigParam16::ID, ok!(CellBuilder::build_from(params)))
241 }
242
243 pub fn get_validator_stake_params(&self) -> Result<ValidatorStakeParams, Error> {
247 ok!(self.get::<ConfigParam17>()).ok_or(Error::CellUnderflow)
248 }
249
250 pub fn set_validator_stake_params(
254 &mut self,
255 params: &ValidatorStakeParams,
256 ) -> Result<bool, Error> {
257 self.set_raw(ConfigParam17::ID, ok!(CellBuilder::build_from(params)))
258 }
259
260 pub fn get_storage_prices(&self) -> Result<Dict<u32, StoragePrices>, Error> {
264 ok!(self.get::<ConfigParam18>()).ok_or(Error::CellUnderflow)
265 }
266
267 pub fn set_storage_prices(&mut self, prices: &[StoragePrices]) -> Result<bool, Error> {
271 let mut dict = Dict::<u32, StoragePrices>::new();
272 for (i, prices) in prices.iter().enumerate() {
273 ok!(dict.set(i as u32, *prices));
274 }
275 self.set_raw(
276 ConfigParam18::ID,
277 ok!(CellBuilder::build_from(NonEmptyDict(dict))),
278 )
279 }
280
281 pub fn get_gas_prices(&self, masterchain: bool) -> Result<GasLimitsPrices, Error> {
285 ok!(if masterchain {
286 self.get::<ConfigParam20>()
287 } else {
288 self.get::<ConfigParam21>()
289 })
290 .ok_or(Error::CellUnderflow)
291 }
292
293 pub fn set_gas_prices(
297 &mut self,
298 masterchain: bool,
299 prices: &GasLimitsPrices,
300 ) -> Result<bool, Error> {
301 let id = if masterchain {
302 ConfigParam20::ID
303 } else {
304 ConfigParam21::ID
305 };
306 self.set_raw(id, ok!(CellBuilder::build_from(prices)))
307 }
308
309 pub fn get_block_limits(&self, masterchain: bool) -> Result<BlockLimits, Error> {
313 ok!(if masterchain {
314 self.get::<ConfigParam22>()
315 } else {
316 self.get::<ConfigParam23>()
317 })
318 .ok_or(Error::CellUnderflow)
319 }
320
321 pub fn set_block_limits(
325 &mut self,
326 masterchain: bool,
327 limits: &BlockLimits,
328 ) -> Result<bool, Error> {
329 let id = if masterchain {
330 ConfigParam22::ID
331 } else {
332 ConfigParam23::ID
333 };
334 self.set_raw(id, ok!(CellBuilder::build_from(limits)))
335 }
336
337 pub fn get_msg_forward_prices(&self, masterchain: bool) -> Result<MsgForwardPrices, Error> {
341 ok!(if masterchain {
342 self.get::<ConfigParam24>()
343 } else {
344 self.get::<ConfigParam25>()
345 })
346 .ok_or(Error::CellUnderflow)
347 }
348
349 pub fn set_msg_forward_prices(
353 &mut self,
354 masterchain: bool,
355 prices: &MsgForwardPrices,
356 ) -> Result<bool, Error> {
357 let id = if masterchain {
358 ConfigParam24::ID
359 } else {
360 ConfigParam25::ID
361 };
362 self.set_raw(id, ok!(CellBuilder::build_from(prices)))
363 }
364
365 #[cfg(not(feature = "tycho"))]
369 pub fn get_catchain_config(&self) -> Result<CatchainConfig, Error> {
370 ok!(self.get::<ConfigParam28>()).ok_or(Error::CellUnderflow)
371 }
372
373 #[cfg(not(feature = "tycho"))]
377 pub fn set_catchain_config(&mut self, config: &CatchainConfig) -> Result<bool, Error> {
378 self.set_raw(ConfigParam28::ID, ok!(CellBuilder::build_from(config)))
379 }
380
381 #[cfg(feature = "tycho")]
385 pub fn get_collation_config(&self) -> Result<CollationConfig, Error> {
386 ok!(self.get::<ConfigParam28>()).ok_or(Error::CellUnderflow)
387 }
388
389 #[cfg(feature = "tycho")]
393 pub fn set_collation_config(&mut self, config: &CollationConfig) -> Result<bool, Error> {
394 self.set_raw(ConfigParam28::ID, ok!(CellBuilder::build_from(config)))
395 }
396
397 pub fn get_consensus_config(&self) -> Result<ConsensusConfig, Error> {
401 ok!(self.get::<ConfigParam29>()).ok_or(Error::CellUnderflow)
402 }
403
404 pub fn set_consensus_config(&mut self, config: &ConsensusConfig) -> Result<bool, Error> {
408 self.set_raw(ConfigParam29::ID, ok!(CellBuilder::build_from(config)))
409 }
410
411 pub fn get_fundamental_addresses(&self) -> Result<Dict<HashBytes, ()>, Error> {
415 ok!(self.get::<ConfigParam31>()).ok_or(Error::CellUnderflow)
416 }
417
418 pub fn set_fundamental_addresses(&mut self, addresses: &[HashBytes]) -> Result<bool, Error> {
422 let mut dict = Dict::<HashBytes, ()>::new();
423 for address in addresses {
424 ok!(dict.set(*address, ()));
425 }
426 self.set_raw(ConfigParam31::ID, ok!(CellBuilder::build_from(dict)))
427 }
428
429 pub fn contains_prev_validator_set(&self) -> Result<bool, Error> {
433 Ok(ok!(self.contains::<ConfigParam32>()) || ok!(self.contains::<ConfigParam33>()))
434 }
435
436 pub fn contains_next_validator_set(&self) -> Result<bool, Error> {
440 Ok(ok!(self.contains::<ConfigParam36>()) || ok!(self.contains::<ConfigParam37>()))
441 }
442
443 pub fn get_previous_validator_set(&self) -> Result<Option<ValidatorSet>, Error> {
447 match ok!(self.get::<ConfigParam33>()) {
448 None => self.get::<ConfigParam32>(),
449 set => Ok(set),
450 }
451 }
452
453 pub fn get_current_validator_set(&self) -> Result<ValidatorSet, Error> {
457 match ok!(self.get::<ConfigParam35>()) {
458 Some(set) => Ok(set),
459 None => ok!(self.get::<ConfigParam34>()).ok_or(Error::CellUnderflow),
460 }
461 }
462
463 pub fn get_next_validator_set(&self) -> Result<Option<ValidatorSet>, Error> {
467 match ok!(self.get::<ConfigParam37>()) {
468 None => self.get::<ConfigParam36>(),
469 set => Ok(set),
470 }
471 }
472
473 pub fn contains<'a, T: KnownConfigParam<'a>>(&'a self) -> Result<bool, Error> {
475 self.0.contains_key(T::ID)
476 }
477
478 pub fn contains_raw(&self, id: u32) -> Result<bool, Error> {
480 self.0.contains_key(id)
481 }
482
483 pub fn get<'a, T: KnownConfigParam<'a>>(&'a self) -> Result<Option<T::Value>, Error> {
485 let Some(mut slice) = ok!(self.get_raw(T::ID)) else {
486 return Ok(None);
487 };
488 match <T::Wrapper as Load<'a>>::load_from(&mut slice) {
489 Ok(wrapped) => Ok(Some(wrapped.into_inner())),
490 Err(e) => Err(e),
491 }
492 }
493
494 pub fn set<'a, T: KnownConfigParam<'a>>(&'a mut self, value: &T::Value) -> Result<bool, Error> {
496 let value = ok!(CellBuilder::build_from(T::Wrapper::wrap_inner(value)));
497 self.set_raw(T::ID, value)
498 }
499
500 pub fn get_raw(&self, id: u32) -> Result<Option<CellSlice<'_>>, Error> {
502 match ok!(self.0.get_raw(id)) {
503 Some(slice) => match slice.get_reference_as_slice(0) {
504 Ok(slice) => Ok(Some(slice)),
505 Err(e) => Err(e),
506 },
507 None => Ok(None),
508 }
509 }
510
511 pub fn set_raw(&mut self, id: u32, value: Cell) -> Result<bool, Error> {
515 self.0.set(id, value)
516 }
517
518 pub fn remove(&mut self, id: u32) -> Result<Option<Cell>, Error> {
523 if id == 0 {
524 return Ok(None);
525 }
526 self.0.remove(id)
527 }
528
529 pub fn as_dict(&self) -> &Dict<u32, Cell> {
531 &self.0
532 }
533}
534
535impl Store for BlockchainConfigParams {
536 fn store_into(&self, builder: &mut CellBuilder, _: &mut dyn CellContext) -> Result<(), Error> {
537 match self.0.root() {
538 Some(root) => builder.store_reference(root.clone()),
539 None => Err(Error::InvalidData),
540 }
541 }
542}
543
544impl<'a> Load<'a> for BlockchainConfigParams {
545 fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
546 let root = ok!(slice.load_reference_cloned());
547 Ok(Self(Dict::from(Some(root))))
548 }
549}
550
551pub trait KnownConfigParam<'a> {
553 const ID: u32;
555
556 type Value;
558
559 type Wrapper: ConfigParamWrapper<Self::Value> + Store + Load<'a>;
561}
562
563pub trait ConfigParamWrapper<T> {
565 fn into_inner(self) -> T;
567
568 fn wrap_inner(inner: &T) -> &Self;
570}
571
572#[repr(transparent)]
574pub struct ParamIdentity<T>(T);
575
576impl<T> ConfigParamWrapper<T> for ParamIdentity<T> {
577 #[inline]
578 fn into_inner(self) -> T {
579 self.0
580 }
581
582 #[inline]
583 fn wrap_inner(inner: &T) -> &Self {
584 unsafe { &*(inner as *const T).cast() }
586 }
587}
588
589impl<'a, T: Load<'a>> Load<'a> for ParamIdentity<T> {
590 #[inline]
591 fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
592 match T::load_from(slice) {
593 Ok(value) => Ok(Self(value)),
594 Err(e) => Err(e),
595 }
596 }
597}
598
599impl<T: Store> Store for ParamIdentity<T> {
600 #[inline]
601 fn store_into(&self, builder: &mut CellBuilder, cx: &mut dyn CellContext) -> Result<(), Error> {
602 self.0.store_into(builder, cx)
603 }
604}
605
606#[cfg(feature = "serde")]
607impl<T: serde::Serialize> serde::Serialize for ParamIdentity<T> {
608 #[inline]
609 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
610 self.0.serialize(serializer)
611 }
612}
613
614#[cfg(feature = "serde")]
615impl<'de, T: serde::Deserialize<'de>> serde::Deserialize<'de> for ParamIdentity<T> {
616 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
617 where
618 D: serde::Deserializer<'de>,
619 {
620 T::deserialize(deserializer).map(Self)
621 }
622}
623
624#[repr(transparent)]
626pub struct NonEmptyDict<T>(T);
627
628impl<T> ConfigParamWrapper<T> for NonEmptyDict<T> {
629 fn into_inner(self) -> T {
630 self.0
631 }
632
633 #[inline]
634 fn wrap_inner(inner: &T) -> &Self {
635 unsafe { &*(inner as *const T).cast() }
637 }
638}
639
640impl<'a, K, V> Load<'a> for NonEmptyDict<Dict<K, V>>
641where
642 K: DictKey,
643{
644 #[inline]
645 fn load_from(slice: &mut CellSlice<'a>) -> Result<Self, Error> {
646 match Dict::load_from_root_ext(slice, &mut Cell::empty_context()) {
647 Ok(value) => Ok(Self(value)),
648 Err(e) => Err(e),
649 }
650 }
651}
652
653impl<K, V> Store for NonEmptyDict<Dict<K, V>> {
654 fn store_into(&self, builder: &mut CellBuilder, _: &mut dyn CellContext) -> Result<(), Error> {
655 match self.0.root() {
656 Some(root) => builder.store_slice(ok!(root.as_slice())),
657 None => Err(Error::InvalidData),
658 }
659 }
660}
661
662#[cfg(feature = "serde")]
663impl serde::Serialize for NonEmptyDict<Dict<u32, ()>> {
664 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
665 use serde::ser::SerializeSeq;
666
667 let mut seq = serializer.serialize_seq(None)?;
668 for entry in self.0.iter() {
669 match entry {
670 Ok((key, _)) => ok!(seq.serialize_element(&key)),
671 Err(e) => return Err(serde::ser::Error::custom(e)),
672 }
673 }
674 seq.end()
675 }
676}
677
678#[cfg(feature = "serde")]
679impl<'de> serde::Deserialize<'de> for NonEmptyDict<Dict<u32, ()>> {
680 #[inline]
681 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
682 use serde::de::Error;
683
684 let parsed = ok!(Vec::<u32>::deserialize(deserializer));
685 if parsed.is_empty() {
686 return Err(Error::custom("dictionary is empty"));
687 }
688
689 let mut res = Dict::new();
690 for item in parsed {
691 ok!(res.set(item, ()).map_err(Error::custom));
692 }
693
694 Ok(Self(res))
695 }
696}
697
698#[cfg(feature = "serde")]
699impl serde::Serialize for NonEmptyDict<Dict<u32, StoragePrices>> {
700 #[inline]
701 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
702 self.0.serialize(serializer)
703 }
704}
705
706#[cfg(feature = "serde")]
707impl<'de> serde::Deserialize<'de> for NonEmptyDict<Dict<u32, StoragePrices>> {
708 #[inline]
709 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
710 let res = ok!(Dict::deserialize(deserializer));
711 if res.is_empty() {
712 return Err(serde::de::Error::custom("dictionary is empty"));
713 }
714 Ok(Self(res))
715 }
716}
717
718macro_rules! define_config_params {
719 ($(
720 $(#[doc = $doc:expr])*
721 $(#[cfg($($cfg_attrs:tt)*)])?
722 $(#[serde($($serde_attrs:tt)*)])?
723 $id:literal => $ident:ident($($ty:tt)*)
724 ),*$(,)?) => {
725 $(
726 $(#[cfg($($cfg_attrs)*)])?
727 $(#[doc = $doc])*
728 pub struct $ident;
729
730 $(#[cfg($($cfg_attrs)*)])?
731 impl<'a> KnownConfigParam<'a> for $ident {
732 const ID: u32 = $id;
733
734 define_config_params!(@wrapper $($ty)*);
735 }
736 )*
737
738 #[cfg(feature = "serde")]
739 impl serde::Serialize for BlockchainConfigParams {
740 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
741 where
742 S: serde::Serializer,
743 {
744 use serde::ser::{Error, SerializeMap};
745
746 let dict = &self.0;
747 if !serializer.is_human_readable() {
748 return crate::boc::BocRepr::serialize(dict, serializer);
749 }
750
751 let mut map = serializer.serialize_map(None)?;
752
753 for entry in dict.iter() {
754 let (key, value) = match entry {
755 Ok(entry) => entry,
756 Err(e) => return Err(Error::custom(e)),
757 };
758
759 {
760 match key {
761 $(
762 $(#[cfg($($cfg_attrs)*)])?
763 $($id => {
764 let value = define_config_params!(
765 @ser
766 $ident,
767 value,
768 $($serde_attrs)*
769 );
770 ok!(map.serialize_entry(&key, &value));
771 },)?
772 )*
773 _ => ok!(map.serialize_entry(&key, value.as_ref())),
774 }
775 }
776 }
777
778 map.end()
779 }
780 }
781
782 #[cfg(feature = "serde")]
783 impl<'de> serde::Deserialize<'de> for BlockchainConfigParams {
784 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
785 where
786 D: serde::Deserializer<'de>,
787 {
788 use serde::de::{Error, Visitor, MapAccess};
789
790 #[derive(serde::Deserialize)]
791 struct RawValue(#[serde(with = "crate::boc::Boc")] Cell);
792
793 struct MapVisitor;
794
795 impl<'de> Visitor<'de> for MapVisitor {
796 type Value = BlockchainConfigParams;
797
798 fn expecting(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
799 f.write_str("a config params map")
800 }
801
802 fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
803 where
804 M: MapAccess<'de>,
805 {
806 let mut dict = Dict::new();
807
808 while let Some(key) = access.next_key::<u32>()? {
809 let value = match key {
810 $(
811 $(#[cfg($($cfg_attrs)*)])?
812 $($id => define_config_params!(
813 @de
814 $ident,
815 access,
816 $($serde_attrs)*
817 ),)?
818 )*
819 _ => {
820 let RawValue(cell) = ok!(access.next_value());
821 cell
822 }
823 };
824 ok!(dict.set(key, value).map_err(Error::custom));
825 }
826
827 Ok(BlockchainConfigParams(dict))
828 }
829 }
830
831 if deserializer.is_human_readable() {
832 deserializer.deserialize_map(MapVisitor)
833 } else {
834 crate::boc::BocRepr::deserialize(deserializer)
835 }
836 }
837 }
838 };
839
840 (@wrapper $wrapper:ident => $($ty:tt)*) => {
841 type Value = $($ty)*;
842 type Wrapper = $wrapper<Self::Value>;
843 };
844 (@wrapper $($ty:tt)*) => {
845 type Value = $($ty)*;
846 type Wrapper = ParamIdentity<Self::Value>;
847 };
848
849 (@ser $ident:ident, $value:ident, transparent) => {{
850 ok!($value.parse::<<$ident as KnownConfigParam>::Wrapper>().map_err(Error::custom))
851 }};
852 (@ser $ident:ident, $value:ident, remote = $remote:ident) => {{
853 let value = ok!($value.parse::<<$ident as KnownConfigParam>::Wrapper>().map_err(Error::custom));
854 $remote(<<$ident as KnownConfigParam>::Wrapper>::into_inner(value))
855 }};
856
857 (@de $ident:ident, $access:ident, transparent) => {{
858 let parsed = ok!($access.next_value::<<$ident as KnownConfigParam>::Wrapper>());
859 ok!(CellBuilder::build_from(&parsed).map_err(Error::custom))
860 }};
861 (@de $ident:ident, $access:ident, remote = $remote:ident) => {{
862 let parsed = ok!($access.next_value::<$remote>());
863 ok!(CellBuilder::build_from(&parsed.0).map_err(Error::custom))
864 }};
865}
866
867define_config_params! {
868 #[serde(transparent)]
870 0 => ConfigParam0(HashBytes),
871
872 #[serde(transparent)]
874 1 => ConfigParam1(HashBytes),
875
876 #[serde(transparent)]
878 2 => ConfigParam2(HashBytes),
879
880 #[serde(transparent)]
882 3 => ConfigParam3(HashBytes),
883
884 #[serde(transparent)]
886 4 => ConfigParam4(HashBytes),
887
888 6 => ConfigParam6(CellSlice<'a>),
890
891 #[serde(transparent)]
893 7 => ConfigParam7(ExtraCurrencyCollection),
894
895 #[serde(transparent)]
899 8 => ConfigParam8(GlobalVersion),
900
901 #[serde(transparent)]
903 9 => ConfigParam9(NonEmptyDict => Dict<u32, ()>),
904
905 #[serde(transparent)]
907 10 => ConfigParam10(NonEmptyDict => Dict<u32, ()>),
908
909 #[serde(transparent)]
913 11 => ConfigParam11(ConfigVotingSetup),
914
915 #[serde(transparent)]
919 12 => ConfigParam12(Dict<i32, WorkchainDescription>),
920
921 13 => ConfigParam13(CellSlice<'a>),
923
924 #[serde(transparent)]
928 14 => ConfigParam14(BlockCreationRewards),
929
930 #[serde(transparent)]
934 15 => ConfigParam15(ElectionTimings),
935
936 #[serde(transparent)]
940 16 => ConfigParam16(ValidatorCountParams),
941
942 #[serde(transparent)]
946 17 => ConfigParam17(ValidatorStakeParams),
947
948 #[serde(transparent)]
952 18 => ConfigParam18(NonEmptyDict => Dict<u32, StoragePrices>),
953
954 #[serde(transparent)]
958 20 => ConfigParam20(GasLimitsPrices),
959
960 #[serde(transparent)]
964 21 => ConfigParam21(GasLimitsPrices),
965
966 #[serde(transparent)]
970 22 => ConfigParam22(BlockLimits),
971
972 #[serde(transparent)]
976 23 => ConfigParam23(BlockLimits),
977
978 #[serde(transparent)]
982 24 => ConfigParam24(MsgForwardPrices),
983
984 #[serde(transparent)]
988 25 => ConfigParam25(MsgForwardPrices),
989
990 #[cfg(not(feature = "tycho"))]
994 #[serde(transparent)]
995 28 => ConfigParam28(CatchainConfig),
996
997 #[cfg(feature = "tycho")]
1001 #[serde(transparent)]
1002 28 => ConfigParam28(CollationConfig),
1003
1004 #[serde(transparent)]
1008 29 => ConfigParam29(ConsensusConfig),
1009
1010 30 => ConfigParam30(CellSlice<'a>),
1012
1013 #[serde(remote = HashBytesList)]
1017 31 => ConfigParam31(Dict<HashBytes, ()>),
1018
1019 #[serde(transparent)]
1023 32 => ConfigParam32(ValidatorSet),
1024
1025 #[serde(transparent)]
1029 33 => ConfigParam33(ValidatorSet),
1030
1031 #[serde(transparent)]
1035 34 => ConfigParam34(ValidatorSet),
1036
1037 #[serde(transparent)]
1041 35 => ConfigParam35(ValidatorSet),
1042
1043 #[serde(transparent)]
1047 36 => ConfigParam36(ValidatorSet),
1048
1049 #[serde(transparent)]
1053 37 => ConfigParam37(ValidatorSet),
1054}
1055
1056#[cfg(feature = "serde")]
1057#[repr(transparent)]
1058struct HashBytesList(Dict<HashBytes, ()>);
1059
1060#[cfg(feature = "serde")]
1061impl serde::Serialize for HashBytesList {
1062 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
1063 use serde::ser::SerializeSeq;
1064
1065 let mut seq = serializer.serialize_seq(None)?;
1066 for entry in self.0.iter() {
1067 match entry {
1068 Ok((ref key, _)) => ok!(seq.serialize_element(key)),
1069 Err(e) => return Err(serde::ser::Error::custom(e)),
1070 }
1071 }
1072 seq.end()
1073 }
1074}
1075
1076#[cfg(feature = "serde")]
1077impl<'de> serde::Deserialize<'de> for HashBytesList {
1078 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1079 where
1080 D: serde::Deserializer<'de>,
1081 {
1082 use serde::de::Error;
1083
1084 let parsed = ok!(Vec::<HashBytes>::deserialize(deserializer));
1085
1086 let mut res = Dict::new();
1087 for item in parsed {
1088 ok!(res.set(item, ()).map_err(Error::custom));
1089 }
1090
1091 Ok(Self(res))
1092 }
1093}