radix_transactions/model/v2/
child_subintent_hashes_v2.rs

1use crate::internal_prelude::*;
2use decompiler::*;
3
4/// Specification of an intent
5#[derive(Debug, Clone, Eq, PartialEq, ManifestSbor, ScryptoDescribe)]
6#[sbor(transparent)]
7pub struct ChildSubintentSpecifiersV2 {
8    pub children: IndexSet<ChildSubintentSpecifier>,
9}
10
11impl TransactionPartialPrepare for ChildSubintentSpecifiersV2 {
12    type Prepared = PreparedChildSubintentSpecifiersV2;
13}
14
15/// A new-type of a [`SubintentHash`], representing that the subintent is claimed
16/// to be a child of the given intent.
17#[derive(Debug, Clone, Eq, Hash, PartialEq, ManifestSbor, ScryptoDescribe)]
18#[sbor(transparent)]
19pub struct ChildSubintentSpecifier {
20    pub hash: SubintentHash,
21}
22
23impl ChildSubintentSpecifier {
24    pub fn decompile_as_pseudo_instruction(
25        &self,
26        context: &mut DecompilationContext,
27    ) -> Result<DecompiledInstruction, DecompileError> {
28        let subintent_id = self.hash.to_string(context.transaction_hash_encoder());
29        let new_named_intent = context.new_named_intent();
30        let intent_name = context.object_names.intent_name(new_named_intent);
31        let instruction = DecompiledInstruction::new("USE_CHILD")
32            .add_raw_argument(format!("NamedIntent(\"{intent_name}\")"))
33            .add_raw_argument(format!("Intent(\"{subintent_id}\")"));
34        Ok(instruction)
35    }
36}
37
38impl From<SubintentHash> for ChildSubintentSpecifier {
39    fn from(hash: SubintentHash) -> Self {
40        Self { hash }
41    }
42}
43
44/// A new-type representing the index of a referenced intent.
45/// The first few of these will be the children of the given intent.
46///
47/// This is referenced in the manifest as `NamedIntent`, like `NamedAddress`.
48/// A static intent address is created as e.g. `Intent("subtxid_...")`, like `Address`.
49///
50/// IMPORTANT: Unlike `Address` and similar, this is NOT its own SBOR manifest value - because
51/// versioning Manifest SBOR was seen as too much work for Cuttlefish. Instead, we use a
52/// ManifestNamedIntentIndex in some places.
53#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
54pub struct ManifestNamedIntent(pub u32);
55
56labelled_resolvable_with_identity_impl!(ManifestNamedIntent, resolver_output: Self);
57
58/// This exists as an unideal serialization target for [`ManifestNamedIntent`],
59/// due to our inability to add a new ManifestCustomValue for the Cuttlefish update.
60/// Instead, we just serialize it directly as a `u32` in the `YIELD_TO_CHILD` instruction.
61#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash, ScryptoDescribe, ManifestSbor)]
62#[sbor(transparent)]
63pub struct ManifestNamedIntentIndex(pub u32);
64
65impl From<ManifestNamedIntentIndex> for ManifestNamedIntent {
66    fn from(value: ManifestNamedIntentIndex) -> Self {
67        Self(value.0)
68    }
69}
70
71impl From<ManifestNamedIntent> for ManifestNamedIntentIndex {
72    fn from(value: ManifestNamedIntent) -> Self {
73        Self(value.0)
74    }
75}
76
77//========
78// prepared
79//========
80
81#[derive(Debug, Clone, Eq, PartialEq)]
82pub struct PreparedChildSubintentSpecifiersV2 {
83    pub children: IndexSet<ChildSubintentSpecifier>,
84    pub summary: Summary,
85}
86
87impl_has_summary!(PreparedChildSubintentSpecifiersV2);
88
89impl TransactionPreparableFromValueBody for PreparedChildSubintentSpecifiersV2 {
90    fn prepare_from_value_body(decoder: &mut TransactionDecoder) -> Result<Self, PrepareError> {
91        let max_child_subintents_per_intent = decoder.settings().max_child_subintents_per_intent;
92        let (hashes, summary) =
93            ConcatenatedDigest::prepare_from_sbor_array_value_body::<Vec<RawHash>>(
94                decoder,
95                ValueType::ChildSubintentSpecifier,
96                max_child_subintents_per_intent,
97            )?;
98
99        let mut children = index_set_with_capacity(hashes.len());
100        for raw_hash in hashes {
101            if !children.insert(ChildSubintentSpecifier {
102                hash: SubintentHash::from_hash(raw_hash.hash),
103            }) {
104                return Err(PrepareError::DecodeError(DecodeError::DuplicateKey));
105            }
106        }
107
108        Ok(Self { children, summary })
109    }
110
111    fn value_kind() -> ManifestValueKind {
112        ManifestValueKind::Array
113    }
114}