1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
use fuel_types::{
    bytes::WORD_SIZE,
    AssetId,
    Bytes32,
    ChainId,
};

const MAX_GAS: u64 = 100_000_000;

/// Consensus configurable parameters used for verifying transactions
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "serde", serde(default))]
pub struct ConsensusParameters {
    /// Maximum contract size, in bytes.
    pub contract_max_size: u64,
    /// Maximum number of inputs.
    pub max_inputs: u64,
    /// Maximum number of outputs.
    pub max_outputs: u64,
    /// Maximum number of witnesses.
    pub max_witnesses: u64,
    /// Maximum gas per transaction.
    pub max_gas_per_tx: u64,
    /// Maximum length of script, in instructions.
    pub max_script_length: u64,
    /// Maximum length of script data, in bytes.
    pub max_script_data_length: u64,
    /// Maximum number of initial storage slots.
    pub max_storage_slots: u64,
    /// Maximum length of predicate, in instructions.
    pub max_predicate_length: u64,
    /// Maximum length of predicate data, in bytes.
    pub max_predicate_data_length: u64,
    /// Maximum gas per predicate
    pub max_gas_per_predicate: u64,
    /// Factor to convert between gas and transaction assets value.
    pub gas_price_factor: u64,
    /// A fixed ratio linking metered bytes to gas price
    pub gas_per_byte: u64,
    /// Maximum length of message data, in bytes.
    pub max_message_data_length: u64,
    /// The unique identifier of this chain
    pub chain_id: ChainId,
}

impl ConsensusParameters {
    /// Default consensus parameters with settings suggested in fuel-specs
    pub const DEFAULT: Self = Self {
        contract_max_size: 16 * 1024 * 1024,
        max_inputs: 255,
        max_outputs: 255,
        max_witnesses: 255,
        max_gas_per_tx: MAX_GAS,
        max_script_length: 1024 * 1024,
        max_script_data_length: 1024 * 1024,
        max_storage_slots: 255,
        max_predicate_length: 1024 * 1024,
        max_predicate_data_length: 1024 * 1024,
        max_gas_per_predicate: MAX_GAS,
        gas_price_factor: 1_000_000_000,
        gas_per_byte: 4,
        max_message_data_length: 1024 * 1024,
        chain_id: ChainId::new(0),
    };

    /// Transaction memory offset in VM runtime
    pub const fn tx_offset(&self) -> usize {
        Bytes32::LEN // Tx ID
            + WORD_SIZE // Tx size
            // Asset ID/Balance coin input pairs
            + self.max_inputs as usize * (AssetId::LEN + WORD_SIZE)
    }

    /// Replace the max contract size with the given argument
    pub const fn with_contract_max_size(mut self, contract_max_size: u64) -> Self {
        self.contract_max_size = contract_max_size;
        self
    }

    /// Replace the max inputs with the given argument
    pub const fn with_max_inputs(mut self, max_inputs: u64) -> Self {
        self.max_inputs = max_inputs;
        self
    }

    /// Replace the max outputs with the given argument
    pub const fn with_max_outputs(mut self, max_outputs: u64) -> Self {
        self.max_outputs = max_outputs;
        self
    }

    /// Replace the max witnesses with the given argument
    pub const fn with_max_witnesses(mut self, max_witnesses: u64) -> Self {
        self.max_witnesses = max_witnesses;
        self
    }

    /// Replace the max gas per transaction with the given argument
    pub const fn with_max_gas_per_tx(mut self, max_gas_per_tx: u64) -> Self {
        self.max_gas_per_tx = max_gas_per_tx;
        self
    }

    /// Replace the max script length with the given argument
    pub const fn with_max_script_length(mut self, max_script_length: u64) -> Self {
        self.max_script_length = max_script_length;
        self
    }

    /// Replace the max script data length with the given argument
    pub const fn with_max_script_data_length(
        mut self,
        max_script_data_length: u64,
    ) -> Self {
        self.max_script_data_length = max_script_data_length;
        self
    }

    /// Replace the max storage slots with the given argument
    pub const fn with_max_storage_slots(mut self, max_storage_slots: u64) -> Self {
        self.max_storage_slots = max_storage_slots;
        self
    }

    /// Replace the max predicate length with the given argument
    pub const fn with_max_predicate_length(mut self, max_predicate_length: u64) -> Self {
        self.max_predicate_length = max_predicate_length;
        self
    }

    /// Replace the max predicate data length with the given argument
    pub const fn with_max_predicate_data_length(
        mut self,
        max_predicate_data_length: u64,
    ) -> Self {
        self.max_predicate_data_length = max_predicate_data_length;
        self
    }

    /// Replace the max gas per predicate with the given argument
    pub const fn with_max_gas_per_predicate(
        mut self,
        max_gas_per_predicate: u64,
    ) -> Self {
        self.max_gas_per_predicate = max_gas_per_predicate;
        self
    }

    /// Replace the gas price factor with the given argument
    pub const fn with_gas_price_factor(mut self, gas_price_factor: u64) -> Self {
        self.gas_price_factor = gas_price_factor;
        self
    }

    pub const fn with_gas_per_byte(mut self, gas_per_byte: u64) -> Self {
        self.gas_per_byte = gas_per_byte;
        self
    }

    /// Replace the max message data length with the given argument
    pub const fn with_max_message_data_length(
        mut self,
        max_message_data_length: u64,
    ) -> Self {
        self.max_message_data_length = max_message_data_length;
        self
    }
}

impl Default for ConsensusParameters {
    fn default() -> Self {
        Self::DEFAULT
    }
}

/// Arbitrary default consensus parameters. While best-efforts are made to adjust these to
/// reasonable settings, they may not be useful for every network instantiation.
#[deprecated(since = "0.12.2", note = "use `ConsensusParameters` instead.")]
pub mod default_parameters {
    use super::ConsensusParameters;
    use fuel_types::ChainId;

    pub const CONTRACT_MAX_SIZE: u64 = ConsensusParameters::DEFAULT.contract_max_size;
    pub const MAX_INPUTS: u64 = ConsensusParameters::DEFAULT.max_inputs;
    pub const MAX_OUTPUTS: u64 = ConsensusParameters::DEFAULT.max_outputs;
    pub const MAX_WITNESSES: u64 = ConsensusParameters::DEFAULT.max_witnesses;
    pub const MAX_GAS_PER_TX: u64 = ConsensusParameters::DEFAULT.max_gas_per_tx;
    pub const MAX_SCRIPT_LENGTH: u64 = ConsensusParameters::DEFAULT.max_script_length;
    pub const MAX_SCRIPT_DATA_LENGTH: u64 =
        ConsensusParameters::DEFAULT.max_script_data_length;
    pub const MAX_STORAGE_SLOTS: u64 = ConsensusParameters::DEFAULT.max_storage_slots;
    pub const MAX_PREDICATE_LENGTH: u64 =
        ConsensusParameters::DEFAULT.max_predicate_length;
    pub const MAX_PREDICATE_DATA_LENGTH: u64 =
        ConsensusParameters::DEFAULT.max_predicate_data_length;
    pub const MAX_GAS_PER_PREDICATE: u64 =
        ConsensusParameters::DEFAULT.max_gas_per_predicate;
    pub const GAS_PRICE_FACTOR: u64 = ConsensusParameters::DEFAULT.gas_price_factor;
    pub const GAS_PER_BYTE: u64 = ConsensusParameters::DEFAULT.gas_per_byte;
    pub const MAX_MESSAGE_DATA_LENGTH: u64 =
        ConsensusParameters::DEFAULT.max_message_data_length;
    pub const CHAIN_ID: ChainId = ConsensusParameters::DEFAULT.chain_id;
}