Skip to main content

dig_constants/
lib.rs

1//! DIG Network Constants
2//!
3//! Defines network parameters for the DIG L2 blockchain. This crate exists
4//! separately so that any DIG crate can import network constants without
5//! pulling in the full CLVM engine or other heavy dependencies.
6//!
7//! The core type is [`NetworkConstants`], which wraps `chia-consensus`'s
8//! `ConsensusConstants` with DIG-specific values (genesis challenge,
9//! AGG_SIG additional data, cost limits, etc.).
10//!
11//! # Usage
12//!
13//! ```rust,ignore
14//! use dig_constants::DIG_MAINNET;
15//!
16//! let genesis = DIG_MAINNET.genesis_challenge();
17//! let consensus = DIG_MAINNET.consensus();
18//! ```
19
20use chia_consensus::consensus_constants::ConsensusConstants;
21use chia_protocol::Bytes32;
22use hex_literal::hex;
23
24/// DIG network constants.
25///
26/// Wraps `chia-consensus::ConsensusConstants` with accessors for the fields
27/// that DIG validators and wallet code commonly need. The underlying
28/// `ConsensusConstants` is available via [`consensus()`](Self::consensus)
29/// for direct use with `chia-consensus` functions like `run_spendbundle()`.
30#[derive(Debug, Clone)]
31pub struct NetworkConstants {
32    inner: ConsensusConstants,
33}
34
35impl NetworkConstants {
36    /// The underlying `chia-consensus` constants, for passing directly to
37    /// `run_spendbundle()`, `validate_clvm_and_signature()`, etc.
38    pub fn consensus(&self) -> &ConsensusConstants {
39        &self.inner
40    }
41
42    /// DIG genesis challenge.
43    pub fn genesis_challenge(&self) -> Bytes32 {
44        self.inner.genesis_challenge
45    }
46
47    /// AGG_SIG_ME additional data (== genesis_challenge on Chia L1).
48    pub fn agg_sig_me_additional_data(&self) -> Bytes32 {
49        self.inner.agg_sig_me_additional_data
50    }
51
52    /// Maximum CLVM cost per block.
53    pub fn max_block_cost_clvm(&self) -> u64 {
54        self.inner.max_block_cost_clvm
55    }
56
57    /// Cost per byte of generator program.
58    pub fn cost_per_byte(&self) -> u64 {
59        self.inner.cost_per_byte
60    }
61
62    /// Maximum coin amount (u64::MAX).
63    pub fn max_coin_amount(&self) -> u64 {
64        self.inner.max_coin_amount
65    }
66}
67
68// =============================================================================
69// AGG_SIG additional data derivation
70//
71// On Chia L1, each AGG_SIG_* variant's additional_data is:
72//   sha256(genesis_challenge || opcode_byte)
73// except AGG_SIG_ME which uses genesis_challenge directly.
74//
75// See: condition_tools.py:58-71
76//   https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/condition_tools.py#L58
77// =============================================================================
78
79// ---------------------------------------------------------------------------
80// DIG Mainnet
81//
82// TODO: Replace placeholder genesis challenge with the real DIG mainnet value
83// once the network is launched. All agg_sig_*_additional_data values must be
84// recomputed as sha256(genesis_challenge || opcode_byte) at that time.
85// ---------------------------------------------------------------------------
86
87/// Placeholder DIG mainnet genesis challenge.
88///
89/// This MUST be replaced with the real value before mainnet launch.
90/// All `agg_sig_*_additional_data` fields are derived from this.
91const DIG_MAINNET_GENESIS_CHALLENGE: [u8; 32] =
92    hex!("0000000000000000000000000000000000000000000000000000000000000000");
93
94/// DIG mainnet constants.
95///
96/// Uses DIG's own genesis challenge and AGG_SIG domain separation.
97/// Proof-of-space and VDF fields are set to neutral values since DIG L2
98/// does not use Chia's proof-of-space consensus.
99pub const DIG_MAINNET: NetworkConstants = NetworkConstants {
100    inner: ConsensusConstants {
101        // -- DIG-specific values --
102        genesis_challenge: Bytes32::new(DIG_MAINNET_GENESIS_CHALLENGE),
103
104        // AGG_SIG additional data: derived from genesis_challenge.
105        // AGG_SIG_ME = genesis_challenge directly.
106        // Others = sha256(genesis_challenge || opcode_byte).
107        // Derivation: condition_tools.py:58-71
108        //   https://github.com/Chia-Network/chia-blockchain/blob/main/chia/consensus/condition_tools.py#L58
109        // Opcode bytes: AGG_SIG_PARENT=43, PUZZLE=44, AMOUNT=45,
110        //   PUZZLE_AMOUNT=46, PARENT_AMOUNT=47, PARENT_PUZZLE=48
111        // NOTE: Recompute ALL values when genesis_challenge is finalized.
112        agg_sig_me_additional_data: Bytes32::new(DIG_MAINNET_GENESIS_CHALLENGE),
113        agg_sig_parent_additional_data: Bytes32::new(hex!(
114            "978722459e638504a3c4ed25b0eae952f1cba668de5a44ccbb3b311eb6901218"
115        )),
116        agg_sig_puzzle_additional_data: Bytes32::new(hex!(
117            "b5b75cf3f16babd124b3c36ac239db038cf9384b6f4343ab65121e7994fa87e4"
118        )),
119        agg_sig_amount_additional_data: Bytes32::new(hex!(
120            "568b7e86b93e78c4a70a90902134266d5f666400d449c827c32422c14a8df42a"
121        )),
122        agg_sig_puzzle_amount_additional_data: Bytes32::new(hex!(
123            "73f82ca7a07025c76c91a3faf2e574ffa13759597fc5d9a0573b4df70245de2e"
124        )),
125        agg_sig_parent_amount_additional_data: Bytes32::new(hex!(
126            "3a2914bb834c69f745c1932450bad277f975b3e1b246d003e3a53e550cf74936"
127        )),
128        agg_sig_parent_puzzle_additional_data: Bytes32::new(hex!(
129            "4f59298d607f3143532ed694fb2f10454a684c1a29ef83e250bf5e234c6720b7"
130        )),
131
132        // DIG L2 cost limits
133        max_block_cost_clvm: 11_000_000_000, // per-spend limit, same as Chia L1
134        cost_per_byte: 12_000,
135        max_coin_amount: u64::MAX,
136
137        // Block generator limits
138        max_generator_size: 1_000_000,
139        max_generator_ref_list_size: 512,
140
141        // Hard fork heights — set to 0 to always use latest consensus rules.
142        // DIG L2 starts with all features enabled from block 0.
143        hard_fork_height: 0,
144        hard_fork2_height: 0,
145
146        // Pre-farm puzzle hashes — not used by DIG L2, set to zero.
147        genesis_pre_farm_pool_puzzle_hash: Bytes32::new([0u8; 32]),
148        genesis_pre_farm_farmer_puzzle_hash: Bytes32::new([0u8; 32]),
149
150        // -- Proof-of-space / VDF fields (not used by DIG L2) --
151        // These must be valid values since ConsensusConstants is passed to
152        // chia-consensus functions, but DIG does not use PoS consensus.
153        slot_blocks_target: 32,
154        min_blocks_per_challenge_block: 16,
155        max_sub_slot_blocks: 128,
156        num_sps_sub_slot: 64,
157        sub_slot_iters_starting: 1 << 27,
158        difficulty_constant_factor: 1 << 67,
159        difficulty_starting: 7,
160        difficulty_change_max_factor: 3,
161        sub_epoch_blocks: 384,
162        epoch_blocks: 4608,
163        significant_bits: 8,
164        discriminant_size_bits: 1024,
165        number_zero_bits_plot_filter_v1: 9,
166        number_zero_bits_plot_filter_v2: 9,
167        min_plot_size_v1: 32,
168        max_plot_size_v1: 50,
169        min_plot_size_v2: 28,
170        max_plot_size_v2: 32,
171        sub_slot_time_target: 600,
172        num_sp_intervals_extra: 3,
173        max_future_time2: 120,
174        number_of_timestamps: 11,
175        max_vdf_witness_size: 64,
176        mempool_block_buffer: 10,
177        weight_proof_threshold: 2,
178        blocks_cache_size: 4608 + (128 * 4),
179        weight_proof_recent_blocks: 1000,
180        max_block_count_per_requests: 32,
181        pool_sub_slot_iters: 37_600_000_000,
182        plot_filter_128_height: 0xffff_ffff,
183        plot_filter_64_height: 0xffff_ffff,
184        plot_filter_32_height: 0xffff_ffff,
185        plot_difficulty_initial: 2,
186        plot_difficulty_4_height: 0xffff_ffff,
187        plot_difficulty_5_height: 0xffff_ffff,
188        plot_difficulty_6_height: 0xffff_ffff,
189        plot_difficulty_7_height: 0xffff_ffff,
190        plot_difficulty_8_height: 0xffff_ffff,
191    },
192};
193
194// ---------------------------------------------------------------------------
195// DIG Testnet
196// ---------------------------------------------------------------------------
197
198/// Placeholder DIG testnet genesis challenge.
199const DIG_TESTNET_GENESIS_CHALLENGE: [u8; 32] =
200    hex!("0000000000000000000000000000000000000000000000000000000000000001");
201
202/// DIG testnet constants.
203///
204/// Same structure as mainnet but with a different genesis challenge.
205/// Useful for testing without risking mainnet state.
206pub const DIG_TESTNET: NetworkConstants = NetworkConstants {
207    inner: ConsensusConstants {
208        genesis_challenge: Bytes32::new(DIG_TESTNET_GENESIS_CHALLENGE),
209        // AGG_SIG_ME = genesis_challenge. Others = sha256(genesis || opcode_byte).
210        agg_sig_me_additional_data: Bytes32::new(DIG_TESTNET_GENESIS_CHALLENGE),
211        agg_sig_parent_additional_data: Bytes32::new(hex!(
212            "6ae3f62deccdc8d56baf955e45dad1d40332a7b8e4afbb38f07719a863658054"
213        )),
214        agg_sig_puzzle_additional_data: Bytes32::new(hex!(
215            "5d962189ce65d3b3799f032add1ab29ef94ebc0e349fe1db231752304cdd6904"
216        )),
217        agg_sig_amount_additional_data: Bytes32::new(hex!(
218            "3724d66f2da5614aa650517a2feb7d681807d5107441c9c72579e9a751b82d67"
219        )),
220        agg_sig_puzzle_amount_additional_data: Bytes32::new(hex!(
221            "fb6a54a5b51e9734a6ff72fe4105cd5db891d4dbaef9361586091f0d4486581b"
222        )),
223        agg_sig_parent_amount_additional_data: Bytes32::new(hex!(
224            "a5556086f1b58dfd5966bf1aac5257c7f60774ffe5a9e219919c56640993f68b"
225        )),
226        agg_sig_parent_puzzle_additional_data: Bytes32::new(hex!(
227            "3fcc94e67cf3975473b065f0b21a4e92dd3df498d8b4464d7da9582669ac4e48"
228        )),
229        // All other fields same as mainnet
230        max_block_cost_clvm: 11_000_000_000,
231        cost_per_byte: 12_000,
232        max_coin_amount: u64::MAX,
233        max_generator_size: 1_000_000,
234        max_generator_ref_list_size: 512,
235        hard_fork_height: 0,
236        hard_fork2_height: 0,
237        genesis_pre_farm_pool_puzzle_hash: Bytes32::new([0u8; 32]),
238        genesis_pre_farm_farmer_puzzle_hash: Bytes32::new([0u8; 32]),
239        slot_blocks_target: 32,
240        min_blocks_per_challenge_block: 16,
241        max_sub_slot_blocks: 128,
242        num_sps_sub_slot: 64,
243        sub_slot_iters_starting: 1 << 27,
244        difficulty_constant_factor: 1 << 67,
245        difficulty_starting: 7,
246        difficulty_change_max_factor: 3,
247        sub_epoch_blocks: 384,
248        epoch_blocks: 4608,
249        significant_bits: 8,
250        discriminant_size_bits: 1024,
251        number_zero_bits_plot_filter_v1: 9,
252        number_zero_bits_plot_filter_v2: 9,
253        min_plot_size_v1: 32,
254        max_plot_size_v1: 50,
255        min_plot_size_v2: 28,
256        max_plot_size_v2: 32,
257        sub_slot_time_target: 600,
258        num_sp_intervals_extra: 3,
259        max_future_time2: 120,
260        number_of_timestamps: 11,
261        max_vdf_witness_size: 64,
262        mempool_block_buffer: 10,
263        weight_proof_threshold: 2,
264        blocks_cache_size: 4608 + (128 * 4),
265        weight_proof_recent_blocks: 1000,
266        max_block_count_per_requests: 32,
267        pool_sub_slot_iters: 37_600_000_000,
268        plot_filter_128_height: 0xffff_ffff,
269        plot_filter_64_height: 0xffff_ffff,
270        plot_filter_32_height: 0xffff_ffff,
271        plot_difficulty_initial: 2,
272        plot_difficulty_4_height: 0xffff_ffff,
273        plot_difficulty_5_height: 0xffff_ffff,
274        plot_difficulty_6_height: 0xffff_ffff,
275        plot_difficulty_7_height: 0xffff_ffff,
276        plot_difficulty_8_height: 0xffff_ffff,
277    },
278};