radix_transactions/validation/
transaction_validation_configuration.rs

1use crate::internal_prelude::*;
2use radix_substate_store_interface::interface::{SubstateDatabase, SubstateDatabaseExtensions};
3
4define_single_versioned! {
5    #[derive(Debug, Copy, Clone, PartialEq, Eq, Sbor)]
6    pub TransactionValidationConfigurationSubstate(TransactionValidationConfigurationVersions) => TransactionValidationConfig = TransactionValidationConfigV1,
7    outer_attributes: [
8        #[derive(ScryptoSborAssertion)]
9        #[sbor_assert(backwards_compatible(
10            cuttlefish = "FILE:transaction_validation_configuration_substate_cuttlefish_schema.bin",
11        ))]
12    ]
13}
14
15impl TransactionValidationConfig {
16    pub fn load(database: &impl SubstateDatabase) -> Self {
17        database
18            .get_substate::<TransactionValidationConfigurationSubstate>(
19                TRANSACTION_TRACKER,
20                BOOT_LOADER_PARTITION,
21                BootLoaderField::TransactionValidationConfiguration,
22            )
23            .map(|s| s.fully_update_and_into_latest_version())
24            .unwrap_or_else(|| Self::babylon())
25    }
26
27    pub(crate) fn allow_notary_to_duplicate_signer(&self, version: TransactionVersion) -> bool {
28        match version {
29            TransactionVersion::V1 => self.v1_transactions_allow_notary_to_duplicate_signer,
30            TransactionVersion::V2 => false,
31        }
32    }
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub enum TransactionVersion {
37    V1,
38    V2,
39}
40
41#[derive(Debug, Copy, Clone, PartialEq, Eq, Sbor)]
42pub struct TransactionValidationConfigV1 {
43    /// Signer signatures only, not including notary signature
44    pub max_signer_signatures_per_intent: usize,
45    pub max_references_per_intent: usize,
46    pub min_tip_percentage: u16,
47    pub max_tip_percentage: u16,
48    pub max_epoch_range: u64,
49    pub max_instructions: usize,
50    pub message_validation: MessageValidationConfig,
51    pub v1_transactions_allow_notary_to_duplicate_signer: bool,
52    pub preparation_settings: PreparationSettingsV1,
53    pub manifest_validation: ManifestValidationRuleset,
54    // V2 settings
55    pub v2_transactions_allowed: bool,
56    pub min_tip_basis_points: u32,
57    pub max_tip_basis_points: u32,
58    /// A setting of N here allows a total depth of N + 1 if you
59    /// include the root transaction intent.
60    pub max_subintent_depth: usize,
61    pub max_total_signature_validations: usize,
62    pub max_total_references: usize,
63}
64
65impl TransactionValidationConfig {
66    pub const fn latest() -> Self {
67        Self::cuttlefish()
68    }
69
70    pub const fn babylon() -> Self {
71        Self {
72            max_signer_signatures_per_intent: 16,
73            max_references_per_intent: usize::MAX,
74            min_tip_percentage: 0,
75            max_tip_percentage: u16::MAX,
76            max_instructions: usize::MAX,
77            // ~30 days given 5 minute epochs
78            max_epoch_range: 12 * 24 * 30,
79            v1_transactions_allow_notary_to_duplicate_signer: true,
80            manifest_validation: ManifestValidationRuleset::BabylonBasicValidator,
81            message_validation: MessageValidationConfig::babylon(),
82            preparation_settings: PreparationSettings::babylon(),
83            // V2-only settings
84            v2_transactions_allowed: true,
85            max_subintent_depth: 0,
86            min_tip_basis_points: 0,
87            max_tip_basis_points: 0,
88            max_total_signature_validations: usize::MAX,
89            max_total_references: usize::MAX,
90        }
91    }
92
93    pub const fn cuttlefish() -> Self {
94        Self {
95            max_references_per_intent: 512,
96            v2_transactions_allowed: true,
97            max_subintent_depth: 3,
98            min_tip_basis_points: 0,
99            max_instructions: 1000,
100            manifest_validation: ManifestValidationRuleset::Interpreter(
101                InterpreterValidationRulesetSpecifier::Cuttlefish,
102            ),
103            // Tip of 100 times the cost of a transaction
104            max_tip_basis_points: 100 * 10000,
105            preparation_settings: PreparationSettings::cuttlefish(),
106            max_total_signature_validations: 64,
107            max_total_references: 512,
108            ..Self::babylon()
109        }
110    }
111}
112
113#[derive(Debug, Copy, Clone, PartialEq, Eq, Sbor)]
114pub enum ManifestValidationRuleset {
115    BabylonBasicValidator,
116    Interpreter(InterpreterValidationRulesetSpecifier),
117}
118
119#[derive(Debug, Copy, Clone, PartialEq, Eq, Sbor)]
120pub struct MessageValidationConfig {
121    pub max_plaintext_message_length: usize,
122    pub max_encrypted_message_length: usize,
123    pub max_mime_type_length: usize,
124    pub max_decryptors: usize,
125}
126
127impl MessageValidationConfig {
128    pub const fn latest() -> Self {
129        Self::babylon()
130    }
131
132    pub const fn babylon() -> Self {
133        Self {
134            max_plaintext_message_length: 2048,
135            max_mime_type_length: 128,
136            max_encrypted_message_length: 2048 + 12 + 16, // Account for IV and MAC - see AesGcmPayload
137            max_decryptors: 20,
138        }
139    }
140}
141
142impl Default for MessageValidationConfig {
143    fn default() -> Self {
144        Self::latest()
145    }
146}