fuel_tx/transaction/
consensus_parameters.rs

1use fuel_types::{
2    bytes::WORD_SIZE,
3    Address,
4    AssetId,
5    Bytes32,
6    ChainId,
7};
8
9pub mod gas;
10
11pub use gas::{
12    DependentCost,
13    GasCostNotDefined,
14    GasCosts,
15    GasCostsValues,
16};
17
18use crate::consts::BALANCE_ENTRY_SIZE;
19
20#[cfg(feature = "test-helpers")]
21const MAX_GAS: u64 = 100_000_000;
22#[cfg(feature = "test-helpers")]
23const MAX_SIZE: u64 = 110 * 1024;
24
25#[derive(Debug, derive_more::Display)]
26#[display("setting block transaction size limit is not supported")]
27pub struct SettingBlockTransactionSizeLimitNotSupported;
28#[cfg(feature = "std")]
29impl std::error::Error for SettingBlockTransactionSizeLimitNotSupported {}
30
31/// A versioned set of consensus parameters.
32#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
33pub enum ConsensusParameters {
34    /// Version 1 of the consensus parameters
35    V1(ConsensusParametersV1),
36    V2(ConsensusParametersV2),
37}
38
39#[cfg(feature = "test-helpers")]
40impl Default for ConsensusParameters {
41    fn default() -> Self {
42        Self::standard()
43    }
44}
45
46impl ConsensusParameters {
47    #[cfg(feature = "test-helpers")]
48    /// Constructor for the `ConsensusParameters` with Standard values.
49    pub fn standard() -> Self {
50        ConsensusParametersV2::standard().into()
51    }
52
53    #[cfg(feature = "test-helpers")]
54    /// Constructor for the `ConsensusParameters` with Standard values around `ChainId`.
55    pub fn standard_with_id(chain_id: ChainId) -> Self {
56        ConsensusParametersV2::standard_with_id(chain_id).into()
57    }
58
59    /// Constructor for the `ConsensusParameters`
60    pub const fn new(
61        tx_params: TxParameters,
62        predicate_params: PredicateParameters,
63        script_params: ScriptParameters,
64        contract_params: ContractParameters,
65        fee_params: FeeParameters,
66        chain_id: ChainId,
67        gas_costs: GasCosts,
68        base_asset_id: AssetId,
69        block_gas_limit: u64,
70        block_transaction_size_limit: u64,
71        privileged_address: Address,
72    ) -> Self {
73        Self::V2(ConsensusParametersV2 {
74            tx_params,
75            predicate_params,
76            script_params,
77            contract_params,
78            fee_params,
79            chain_id,
80            gas_costs,
81            base_asset_id,
82            block_gas_limit,
83            block_transaction_size_limit,
84            privileged_address,
85        })
86    }
87
88    /// Get the transaction parameters
89    pub const fn tx_params(&self) -> &TxParameters {
90        match self {
91            Self::V1(params) => &params.tx_params,
92            Self::V2(params) => &params.tx_params,
93        }
94    }
95
96    /// Get the predicate parameters
97    pub const fn predicate_params(&self) -> &PredicateParameters {
98        match self {
99            Self::V1(params) => &params.predicate_params,
100            Self::V2(params) => &params.predicate_params,
101        }
102    }
103
104    /// Get the script parameters
105    pub const fn script_params(&self) -> &ScriptParameters {
106        match self {
107            Self::V1(params) => &params.script_params,
108            Self::V2(params) => &params.script_params,
109        }
110    }
111
112    /// Get the contract parameters
113    pub const fn contract_params(&self) -> &ContractParameters {
114        match self {
115            Self::V1(params) => &params.contract_params,
116            Self::V2(params) => &params.contract_params,
117        }
118    }
119
120    /// Get the fee parameters
121    pub const fn fee_params(&self) -> &FeeParameters {
122        match self {
123            Self::V1(params) => &params.fee_params,
124            Self::V2(params) => &params.fee_params,
125        }
126    }
127
128    /// Get the chain ID
129    pub const fn chain_id(&self) -> ChainId {
130        match self {
131            Self::V1(params) => params.chain_id,
132            Self::V2(params) => params.chain_id,
133        }
134    }
135
136    /// Get the gas costs
137    pub const fn gas_costs(&self) -> &GasCosts {
138        match self {
139            Self::V1(params) => &params.gas_costs,
140            Self::V2(params) => &params.gas_costs,
141        }
142    }
143
144    /// Get the base asset ID
145    pub const fn base_asset_id(&self) -> &AssetId {
146        match self {
147            Self::V1(params) => &params.base_asset_id,
148            Self::V2(params) => &params.base_asset_id,
149        }
150    }
151
152    /// Get the block gas limit
153    pub const fn block_gas_limit(&self) -> u64 {
154        match self {
155            Self::V1(params) => params.block_gas_limit,
156            Self::V2(params) => params.block_gas_limit,
157        }
158    }
159
160    /// Get the block transaction size limit
161    pub fn block_transaction_size_limit(&self) -> u64 {
162        match self {
163            Self::V1(_) => {
164                // In V1 there was no limit on the transaction size. For the sake of
165                // backwards compatibility we allow for a largest limit possible.
166                u64::MAX
167            }
168            Self::V2(params) => params.block_transaction_size_limit,
169        }
170    }
171
172    /// Get the privileged address
173    pub const fn privileged_address(&self) -> &Address {
174        match self {
175            Self::V1(params) => &params.privileged_address,
176            Self::V2(params) => &params.privileged_address,
177        }
178    }
179}
180
181impl ConsensusParameters {
182    /// Set the transaction parameters.
183    pub fn set_tx_params(&mut self, tx_params: TxParameters) {
184        match self {
185            Self::V1(params) => params.tx_params = tx_params,
186            Self::V2(params) => params.tx_params = tx_params,
187        }
188    }
189
190    /// Set the predicate parameters.
191    pub fn set_predicate_params(&mut self, predicate_params: PredicateParameters) {
192        match self {
193            Self::V1(params) => params.predicate_params = predicate_params,
194            Self::V2(params) => params.predicate_params = predicate_params,
195        }
196    }
197
198    /// Set the script parameters.
199    pub fn set_script_params(&mut self, script_params: ScriptParameters) {
200        match self {
201            Self::V1(params) => params.script_params = script_params,
202            Self::V2(params) => params.script_params = script_params,
203        }
204    }
205
206    /// Set the contract parameters.
207    pub fn set_contract_params(&mut self, contract_params: ContractParameters) {
208        match self {
209            Self::V1(params) => params.contract_params = contract_params,
210            Self::V2(params) => params.contract_params = contract_params,
211        }
212    }
213
214    /// Set the fee parameters.
215    pub fn set_fee_params(&mut self, fee_params: FeeParameters) {
216        match self {
217            Self::V1(params) => params.fee_params = fee_params,
218            Self::V2(params) => params.fee_params = fee_params,
219        }
220    }
221
222    /// Set the chain ID.
223    pub fn set_chain_id(&mut self, chain_id: ChainId) {
224        match self {
225            Self::V1(params) => params.chain_id = chain_id,
226            Self::V2(params) => params.chain_id = chain_id,
227        }
228    }
229
230    /// Set the gas costs.
231    pub fn set_gas_costs(&mut self, gas_costs: GasCosts) {
232        match self {
233            Self::V1(params) => params.gas_costs = gas_costs,
234            Self::V2(params) => params.gas_costs = gas_costs,
235        }
236    }
237
238    /// Set the base asset ID.
239    pub fn set_base_asset_id(&mut self, base_asset_id: AssetId) {
240        match self {
241            Self::V1(params) => params.base_asset_id = base_asset_id,
242            Self::V2(params) => params.base_asset_id = base_asset_id,
243        }
244    }
245
246    /// Set the block gas limit.
247    pub fn set_block_gas_limit(&mut self, block_gas_limit: u64) {
248        match self {
249            Self::V1(params) => params.block_gas_limit = block_gas_limit,
250            Self::V2(params) => params.block_gas_limit = block_gas_limit,
251        }
252    }
253
254    /// Set the block transaction size limit.
255    pub fn set_block_transaction_size_limit(
256        &mut self,
257        block_transaction_size_limit: u64,
258    ) -> Result<(), SettingBlockTransactionSizeLimitNotSupported> {
259        match self {
260            Self::V1(_) => Err(SettingBlockTransactionSizeLimitNotSupported),
261            Self::V2(params) => {
262                params.block_transaction_size_limit = block_transaction_size_limit;
263                Ok(())
264            }
265        }
266    }
267
268    /// Set the privileged address.
269    pub fn set_privileged_address(&mut self, privileged_address: Address) {
270        match self {
271            Self::V1(params) => params.privileged_address = privileged_address,
272            Self::V2(params) => params.privileged_address = privileged_address,
273        }
274    }
275}
276
277/// A collection of parameters for convenience
278#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
279pub struct ConsensusParametersV1 {
280    pub tx_params: TxParameters,
281    pub predicate_params: PredicateParameters,
282    pub script_params: ScriptParameters,
283    pub contract_params: ContractParameters,
284    pub fee_params: FeeParameters,
285    pub chain_id: ChainId,
286    pub gas_costs: GasCosts,
287    pub base_asset_id: AssetId,
288    pub block_gas_limit: u64,
289    /// The privileged address(user or predicate) that can perform permissioned
290    /// operations(like upgrading the network).
291    pub privileged_address: Address,
292}
293
294#[cfg(feature = "test-helpers")]
295impl ConsensusParametersV1 {
296    /// Constructor for the `ConsensusParameters` with Standard values.
297    pub fn standard() -> Self {
298        Self::standard_with_id(ChainId::default())
299    }
300
301    /// Constructor for the `ConsensusParameters` with Standard values around `ChainId`.
302    pub fn standard_with_id(chain_id: ChainId) -> Self {
303        Self {
304            tx_params: TxParameters::DEFAULT,
305            predicate_params: PredicateParameters::DEFAULT,
306            script_params: ScriptParameters::DEFAULT,
307            contract_params: ContractParameters::DEFAULT,
308            fee_params: FeeParameters::DEFAULT,
309            chain_id,
310            gas_costs: GasCosts::default(),
311            base_asset_id: Default::default(),
312            block_gas_limit: TxParameters::DEFAULT.max_gas_per_tx(),
313            privileged_address: Default::default(),
314        }
315    }
316}
317
318#[cfg(feature = "test-helpers")]
319impl Default for ConsensusParametersV1 {
320    fn default() -> Self {
321        Self::standard()
322    }
323}
324
325impl From<ConsensusParametersV1> for ConsensusParameters {
326    fn from(params: ConsensusParametersV1) -> Self {
327        Self::V1(params)
328    }
329}
330
331/// A collection of parameters for convenience
332/// The difference with [`ConsensusParametersV1`]:
333/// - `block_transaction_size_limit` has been added.
334#[derive(Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
335pub struct ConsensusParametersV2 {
336    pub tx_params: TxParameters,
337    pub predicate_params: PredicateParameters,
338    pub script_params: ScriptParameters,
339    pub contract_params: ContractParameters,
340    pub fee_params: FeeParameters,
341    pub chain_id: ChainId,
342    pub gas_costs: GasCosts,
343    pub base_asset_id: AssetId,
344    pub block_gas_limit: u64,
345    pub block_transaction_size_limit: u64,
346    /// The privileged address(user or predicate) that can perform permissioned
347    /// operations(like upgrading the network).
348    pub privileged_address: Address,
349}
350
351#[cfg(feature = "test-helpers")]
352impl ConsensusParametersV2 {
353    const DEFAULT_BLOCK_TRANSACTION_SIZE_LIMIT: u64 = 126 * 1024;
354
355    /// Constructor for the `ConsensusParameters` with Standard values.
356    pub fn standard() -> Self {
357        Self::standard_with_id(ChainId::default())
358    }
359
360    /// Constructor for the `ConsensusParameters` with Standard values around `ChainId`.
361    pub fn standard_with_id(chain_id: ChainId) -> Self {
362        Self {
363            tx_params: TxParameters::DEFAULT,
364            predicate_params: PredicateParameters::DEFAULT,
365            script_params: ScriptParameters::DEFAULT,
366            contract_params: ContractParameters::DEFAULT,
367            fee_params: FeeParameters::DEFAULT,
368            chain_id,
369            gas_costs: GasCosts::default(),
370            base_asset_id: Default::default(),
371            block_gas_limit: TxParameters::DEFAULT.max_gas_per_tx(),
372            block_transaction_size_limit: Self::DEFAULT_BLOCK_TRANSACTION_SIZE_LIMIT,
373            privileged_address: Default::default(),
374        }
375    }
376}
377
378#[cfg(feature = "test-helpers")]
379impl Default for ConsensusParametersV2 {
380    fn default() -> Self {
381        Self::standard()
382    }
383}
384
385impl From<ConsensusParametersV2> for ConsensusParameters {
386    fn from(params: ConsensusParametersV2) -> Self {
387        Self::V2(params)
388    }
389}
390
391/// The versioned fee parameters.
392#[derive(
393    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
394)]
395pub enum FeeParameters {
396    V1(FeeParametersV1),
397}
398
399impl FeeParameters {
400    #[cfg(feature = "test-helpers")]
401    /// Default fee parameters just for testing.
402    pub const DEFAULT: Self = Self::V1(FeeParametersV1::DEFAULT);
403
404    /// Replace the gas price factor with the given argument
405    pub const fn with_gas_price_factor(self, gas_price_factor: u64) -> Self {
406        match self {
407            Self::V1(mut params) => {
408                params.gas_price_factor = gas_price_factor;
409                Self::V1(params)
410            }
411        }
412    }
413
414    pub const fn with_gas_per_byte(self, gas_per_byte: u64) -> Self {
415        match self {
416            Self::V1(mut params) => {
417                params.gas_per_byte = gas_per_byte;
418                Self::V1(params)
419            }
420        }
421    }
422}
423
424impl FeeParameters {
425    /// Get the gas price factor
426    pub const fn gas_price_factor(&self) -> u64 {
427        match self {
428            Self::V1(params) => params.gas_price_factor,
429        }
430    }
431
432    /// Get the gas per byte
433    pub const fn gas_per_byte(&self) -> u64 {
434        match self {
435            Self::V1(params) => params.gas_per_byte,
436        }
437    }
438}
439
440#[cfg(feature = "test-helpers")]
441impl Default for FeeParameters {
442    fn default() -> Self {
443        Self::DEFAULT
444    }
445}
446
447impl From<FeeParametersV1> for FeeParameters {
448    fn from(params: FeeParametersV1) -> Self {
449        Self::V1(params)
450    }
451}
452
453/// Consensus configurable parameters used for verifying transactions
454#[derive(
455    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
456)]
457pub struct FeeParametersV1 {
458    /// Factor to convert between gas and transaction assets value.
459    pub gas_price_factor: u64,
460    /// A fixed ratio linking metered bytes to gas price
461    pub gas_per_byte: u64,
462}
463
464#[cfg(feature = "test-helpers")]
465impl FeeParametersV1 {
466    /// Default fee parameters just for tests.
467    pub const DEFAULT: Self = FeeParametersV1 {
468        gas_price_factor: 1_000_000_000,
469        gas_per_byte: 4,
470    };
471}
472
473#[cfg(feature = "test-helpers")]
474impl Default for FeeParametersV1 {
475    fn default() -> Self {
476        Self::DEFAULT
477    }
478}
479
480/// Versioned predicate parameters.
481#[derive(
482    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
483)]
484pub enum PredicateParameters {
485    V1(PredicateParametersV1),
486}
487
488impl PredicateParameters {
489    #[cfg(feature = "test-helpers")]
490    /// Default parameters just for testing.
491    pub const DEFAULT: Self = Self::V1(PredicateParametersV1::DEFAULT);
492
493    /// Replace the max predicate length with the given argument
494    pub const fn with_max_predicate_length(self, max_predicate_length: u64) -> Self {
495        match self {
496            Self::V1(mut params) => {
497                params.max_predicate_length = max_predicate_length;
498                Self::V1(params)
499            }
500        }
501    }
502
503    /// Replace the max predicate data length with the given argument
504    pub const fn with_max_predicate_data_length(
505        self,
506        max_predicate_data_length: u64,
507    ) -> Self {
508        match self {
509            Self::V1(mut params) => {
510                params.max_predicate_data_length = max_predicate_data_length;
511                Self::V1(params)
512            }
513        }
514    }
515
516    /// Replace the max message data length with the given argument
517    pub const fn with_max_message_data_length(
518        self,
519        max_message_data_length: u64,
520    ) -> Self {
521        match self {
522            Self::V1(mut params) => {
523                params.max_message_data_length = max_message_data_length;
524                Self::V1(params)
525            }
526        }
527    }
528
529    /// Replace the max gas per predicate.
530    pub const fn with_max_gas_per_predicate(self, max_gas_per_predicate: u64) -> Self {
531        match self {
532            Self::V1(mut params) => {
533                params.max_gas_per_predicate = max_gas_per_predicate;
534                Self::V1(params)
535            }
536        }
537    }
538}
539
540impl PredicateParameters {
541    /// Get the maximum predicate length
542    pub const fn max_predicate_length(&self) -> u64 {
543        match self {
544            Self::V1(params) => params.max_predicate_length,
545        }
546    }
547
548    /// Get the maximum predicate data length
549    pub const fn max_predicate_data_length(&self) -> u64 {
550        match self {
551            Self::V1(params) => params.max_predicate_data_length,
552        }
553    }
554
555    /// Get the maximum message data length
556    pub const fn max_message_data_length(&self) -> u64 {
557        match self {
558            Self::V1(params) => params.max_message_data_length,
559        }
560    }
561
562    /// Get the maximum gas per predicate
563    pub const fn max_gas_per_predicate(&self) -> u64 {
564        match self {
565            Self::V1(params) => params.max_gas_per_predicate,
566        }
567    }
568}
569
570impl From<PredicateParametersV1> for PredicateParameters {
571    fn from(params: PredicateParametersV1) -> Self {
572        Self::V1(params)
573    }
574}
575
576#[cfg(feature = "test-helpers")]
577impl Default for PredicateParameters {
578    fn default() -> Self {
579        Self::DEFAULT
580    }
581}
582
583/// Consensus configurable parameters used for verifying transactions
584#[derive(
585    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
586)]
587pub struct PredicateParametersV1 {
588    /// Maximum length of predicate, in instructions.
589    pub max_predicate_length: u64,
590    /// Maximum length of predicate data, in bytes.
591    pub max_predicate_data_length: u64,
592    /// Maximum length of message data, in bytes.
593    pub max_message_data_length: u64,
594    /// Maximum gas spent per predicate
595    pub max_gas_per_predicate: u64,
596}
597
598#[cfg(feature = "test-helpers")]
599impl PredicateParametersV1 {
600    /// Default parameters just for testing.
601    pub const DEFAULT: Self = Self {
602        max_predicate_length: 1024 * 1024,
603        max_predicate_data_length: 1024 * 1024,
604        max_message_data_length: 1024 * 1024,
605        max_gas_per_predicate: MAX_GAS,
606    };
607}
608
609#[cfg(feature = "test-helpers")]
610impl Default for PredicateParametersV1 {
611    fn default() -> Self {
612        Self::DEFAULT
613    }
614}
615
616/// Versioned transaction parameters.
617#[derive(
618    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
619)]
620pub enum TxParameters {
621    /// Version 1 of the transaction parameters.
622    V1(TxParametersV1),
623}
624
625impl TxParameters {
626    #[cfg(feature = "test-helpers")]
627    /// Default parameters just for testing.
628    pub const DEFAULT: Self = Self::V1(TxParametersV1::DEFAULT);
629
630    /// Transaction memory offset in VM runtime
631    pub const fn tx_offset(&self) -> usize {
632        let Some(balances_size) =
633            (self.max_inputs() as usize).checked_mul(BALANCE_ENTRY_SIZE)
634        else {
635            panic!(
636                "Consensus parameters shouldn't allow max_inputs to cause overflow here"
637            );
638        };
639
640        balances_size.saturating_add(
641            Bytes32::LEN // Tx ID
642            + WORD_SIZE // Tx size
643            + AssetId::LEN, // Base asset ID
644        )
645    }
646
647    /// Replace the max inputs with the given argument
648    pub const fn with_max_inputs(self, max_inputs: u16) -> Self {
649        match self {
650            Self::V1(mut params) => {
651                params.max_inputs = max_inputs;
652                Self::V1(params)
653            }
654        }
655    }
656
657    /// Replace the max outputs with the given argument
658    pub const fn with_max_outputs(self, max_outputs: u16) -> Self {
659        match self {
660            Self::V1(mut params) => {
661                params.max_outputs = max_outputs;
662                Self::V1(params)
663            }
664        }
665    }
666
667    /// Replace the max witnesses with the given argument
668    pub const fn with_max_witnesses(self, max_witnesses: u32) -> Self {
669        match self {
670            Self::V1(mut params) => {
671                params.max_witnesses = max_witnesses;
672                Self::V1(params)
673            }
674        }
675    }
676
677    /// Replace the max gas per transaction with the given argument
678    pub const fn with_max_gas_per_tx(self, max_gas_per_tx: u64) -> Self {
679        match self {
680            Self::V1(mut params) => {
681                params.max_gas_per_tx = max_gas_per_tx;
682                Self::V1(params)
683            }
684        }
685    }
686
687    /// Replace the max size of the transaction with the given argument
688    pub const fn with_max_size(self, max_size: u64) -> Self {
689        match self {
690            Self::V1(mut params) => {
691                params.max_size = max_size;
692                Self::V1(params)
693            }
694        }
695    }
696
697    /// Replace the max bytecode subsections with the given argument
698    pub const fn with_max_bytecode_subsections(
699        self,
700        max_bytecode_subsections: u16,
701    ) -> Self {
702        match self {
703            Self::V1(mut params) => {
704                params.max_bytecode_subsections = max_bytecode_subsections;
705                Self::V1(params)
706            }
707        }
708    }
709}
710
711impl TxParameters {
712    /// Get the maximum number of inputs
713    pub const fn max_inputs(&self) -> u16 {
714        match self {
715            Self::V1(params) => params.max_inputs,
716        }
717    }
718
719    /// Get the maximum number of outputs
720    pub const fn max_outputs(&self) -> u16 {
721        match self {
722            Self::V1(params) => params.max_outputs,
723        }
724    }
725
726    /// Get the maximum number of witnesses
727    pub const fn max_witnesses(&self) -> u32 {
728        match self {
729            Self::V1(params) => params.max_witnesses,
730        }
731    }
732
733    /// Get the maximum gas per transaction
734    pub const fn max_gas_per_tx(&self) -> u64 {
735        match self {
736            Self::V1(params) => params.max_gas_per_tx,
737        }
738    }
739
740    /// Get the maximum size in bytes
741    pub const fn max_size(&self) -> u64 {
742        match self {
743            Self::V1(params) => params.max_size,
744        }
745    }
746
747    /// Get the maximum number of bytecode subsections.
748    pub const fn max_bytecode_subsections(&self) -> u16 {
749        match self {
750            Self::V1(params) => params.max_bytecode_subsections,
751        }
752    }
753}
754
755#[cfg(feature = "test-helpers")]
756impl Default for TxParameters {
757    fn default() -> Self {
758        Self::DEFAULT
759    }
760}
761
762#[cfg(feature = "test-helpers")]
763impl TxParameters {
764    pub fn set_max_size(&mut self, max_size: u64) {
765        match self {
766            Self::V1(params) => params.max_size = max_size,
767        }
768    }
769}
770
771impl From<TxParametersV1> for TxParameters {
772    fn from(params: TxParametersV1) -> Self {
773        Self::V1(params)
774    }
775}
776
777#[derive(
778    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
779)]
780pub struct TxParametersV1 {
781    /// Maximum number of inputs.
782    pub max_inputs: u16,
783    /// Maximum number of outputs.
784    pub max_outputs: u16,
785    /// Maximum number of witnesses.
786    pub max_witnesses: u32,
787    /// Maximum gas per transaction.
788    pub max_gas_per_tx: u64,
789    /// Maximum size in bytes
790    pub max_size: u64,
791    /// Maximum number of bytecode subsections.
792    pub max_bytecode_subsections: u16,
793}
794
795#[cfg(feature = "test-helpers")]
796impl TxParametersV1 {
797    /// Default parameters just for testing.
798    pub const DEFAULT: Self = Self {
799        max_inputs: 255,
800        max_outputs: 255,
801        max_witnesses: 255,
802        max_gas_per_tx: MAX_GAS,
803        max_size: MAX_SIZE,
804        max_bytecode_subsections: 255,
805    };
806}
807
808#[cfg(feature = "test-helpers")]
809impl Default for TxParametersV1 {
810    fn default() -> Self {
811        Self::DEFAULT
812    }
813}
814
815/// Versioned script parameters.
816#[derive(
817    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
818)]
819pub enum ScriptParameters {
820    V1(ScriptParametersV1),
821}
822
823impl ScriptParameters {
824    #[cfg(feature = "test-helpers")]
825    /// Default parameters just for testing.
826    pub const DEFAULT: Self = Self::V1(ScriptParametersV1::DEFAULT);
827
828    /// Replace the max script length with the given argument
829    pub const fn with_max_script_length(self, max_script_length: u64) -> Self {
830        match self {
831            Self::V1(mut params) => {
832                params.max_script_length = max_script_length;
833                Self::V1(params)
834            }
835        }
836    }
837
838    /// Replace the max script data length with the given argument
839    pub const fn with_max_script_data_length(self, max_script_data_length: u64) -> Self {
840        match self {
841            Self::V1(mut params) => {
842                params.max_script_data_length = max_script_data_length;
843                Self::V1(params)
844            }
845        }
846    }
847}
848
849impl ScriptParameters {
850    /// Get the maximum script length
851    pub const fn max_script_length(&self) -> u64 {
852        match self {
853            Self::V1(params) => params.max_script_length,
854        }
855    }
856
857    /// Get the maximum script data length
858    pub const fn max_script_data_length(&self) -> u64 {
859        match self {
860            Self::V1(params) => params.max_script_data_length,
861        }
862    }
863}
864
865impl From<ScriptParametersV1> for ScriptParameters {
866    fn from(params: ScriptParametersV1) -> Self {
867        Self::V1(params)
868    }
869}
870
871#[cfg(feature = "test-helpers")]
872impl Default for ScriptParameters {
873    fn default() -> Self {
874        Self::DEFAULT
875    }
876}
877
878#[derive(
879    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
880)]
881pub struct ScriptParametersV1 {
882    /// Maximum length of script, in instructions.
883    pub max_script_length: u64,
884    /// Maximum length of script data, in bytes.
885    pub max_script_data_length: u64,
886}
887
888#[cfg(feature = "test-helpers")]
889impl ScriptParametersV1 {
890    /// Default parameters just for testing.
891    pub const DEFAULT: Self = Self {
892        max_script_length: 1024 * 1024,
893        max_script_data_length: 1024 * 1024,
894    };
895}
896
897#[cfg(feature = "test-helpers")]
898impl Default for ScriptParametersV1 {
899    fn default() -> Self {
900        Self::DEFAULT
901    }
902}
903
904/// Versioned contract parameters.
905#[derive(
906    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
907)]
908pub enum ContractParameters {
909    V1(ContractParametersV1),
910}
911
912impl ContractParameters {
913    #[cfg(feature = "test-helpers")]
914    /// Default parameters just for testing.
915    pub const DEFAULT: Self = Self::V1(ContractParametersV1::DEFAULT);
916
917    /// Replace the max contract size with the given argument
918    pub const fn with_contract_max_size(self, contract_max_size: u64) -> Self {
919        match self {
920            Self::V1(mut params) => {
921                params.contract_max_size = contract_max_size;
922                Self::V1(params)
923            }
924        }
925    }
926
927    /// Replace the max storage slots with the given argument
928    pub const fn with_max_storage_slots(self, max_storage_slots: u64) -> Self {
929        match self {
930            Self::V1(mut params) => {
931                params.max_storage_slots = max_storage_slots;
932                Self::V1(params)
933            }
934        }
935    }
936}
937
938impl ContractParameters {
939    /// Get the maximum contract size
940    pub const fn contract_max_size(&self) -> u64 {
941        match self {
942            Self::V1(params) => params.contract_max_size,
943        }
944    }
945
946    /// Get the maximum storage slots
947    pub const fn max_storage_slots(&self) -> u64 {
948        match self {
949            Self::V1(params) => params.max_storage_slots,
950        }
951    }
952}
953
954impl From<ContractParametersV1> for ContractParameters {
955    fn from(params: ContractParametersV1) -> Self {
956        Self::V1(params)
957    }
958}
959
960#[cfg(feature = "test-helpers")]
961impl Default for ContractParameters {
962    fn default() -> Self {
963        Self::DEFAULT
964    }
965}
966
967#[derive(
968    Copy, Clone, Debug, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
969)]
970pub struct ContractParametersV1 {
971    /// Maximum contract size, in bytes.
972    pub contract_max_size: u64,
973
974    /// Maximum number of initial storage slots.
975    pub max_storage_slots: u64,
976}
977
978#[cfg(feature = "test-helpers")]
979impl ContractParametersV1 {
980    /// Default parameters just for testing.
981    pub const DEFAULT: Self = Self {
982        contract_max_size: 100 * 1024,
983        max_storage_slots: 255,
984    };
985}
986
987#[cfg(feature = "test-helpers")]
988impl Default for ContractParametersV1 {
989    fn default() -> Self {
990        Self::DEFAULT
991    }
992}
993
994#[cfg(feature = "typescript")]
995pub mod typescript {
996    use wasm_bindgen::prelude::*;
997
998    use super::{
999        PredicateParameters as PredicateParametersRust,
1000        PredicateParametersV1,
1001    };
1002
1003    #[derive(Clone, Debug, PartialEq, Eq, Hash)]
1004    #[cfg_attr(feature = "typescript", wasm_bindgen::prelude::wasm_bindgen)]
1005    pub struct PredicateParameters(alloc::boxed::Box<PredicateParametersRust>);
1006
1007    impl AsRef<PredicateParametersRust> for PredicateParameters {
1008        fn as_ref(&self) -> &PredicateParametersRust {
1009            &self.0
1010        }
1011    }
1012
1013    #[wasm_bindgen]
1014    impl PredicateParameters {
1015        #[wasm_bindgen(constructor)]
1016        pub fn typescript_new(
1017            max_predicate_length: u64,
1018            max_predicate_data_length: u64,
1019            max_message_data_length: u64,
1020            max_gas_per_predicate: u64,
1021        ) -> Self {
1022            let params: PredicateParametersRust = PredicateParametersV1 {
1023                max_predicate_length,
1024                max_predicate_data_length,
1025                max_message_data_length,
1026                max_gas_per_predicate,
1027            }
1028            .into();
1029
1030            PredicateParameters(params.into())
1031        }
1032    }
1033}
1034
1035#[cfg(test)]
1036mod tests {
1037    use crate::consensus_parameters::{
1038        ConsensusParametersV2,
1039        SettingBlockTransactionSizeLimitNotSupported,
1040    };
1041
1042    use super::{
1043        ConsensusParameters,
1044        ConsensusParametersV1,
1045    };
1046
1047    #[test]
1048    fn error_when_setting_block_size_limit_in_consensus_parameters_v1() {
1049        let mut consensus_params: ConsensusParameters =
1050            ConsensusParametersV1::default().into();
1051
1052        let result = consensus_params.set_block_transaction_size_limit(0);
1053
1054        assert!(matches!(
1055            result,
1056            Err(SettingBlockTransactionSizeLimitNotSupported)
1057        ))
1058    }
1059
1060    #[test]
1061    fn ok_when_setting_block_size_limit_in_consensus_parameters_v2() {
1062        let mut consensus_params: ConsensusParameters =
1063            ConsensusParametersV2::default().into();
1064
1065        let result = consensus_params.set_block_transaction_size_limit(0);
1066
1067        assert!(matches!(result, Ok(())))
1068    }
1069}