snarkvm_ledger_block/header/
mod.rs1mod metadata;
17pub use metadata::*;
18
19mod bytes;
20mod genesis;
21mod merkle;
22mod serialize;
23mod string;
24mod verify;
25
26use crate::{Ratifications, Transactions};
27use console::{
28 network::prelude::*,
29 program::{HEADER_DEPTH, HeaderLeaf, HeaderPath, HeaderTree},
30 types::Field,
31};
32use snarkvm_synthesizer_program::FinalizeOperation;
33
34#[derive(Copy, Clone, PartialEq, Eq, Hash)]
36pub struct Header<N: Network> {
37 previous_state_root: N::StateRoot,
39 transactions_root: Field<N>,
41 finalize_root: Field<N>,
43 ratifications_root: Field<N>,
45 solutions_root: Field<N>,
47 subdag_root: Field<N>,
49 metadata: Metadata<N>,
51}
52
53impl<N: Network> Header<N> {
54 pub fn from(
56 previous_state_root: N::StateRoot,
57 transactions_root: Field<N>,
58 finalize_root: Field<N>,
59 ratifications_root: Field<N>,
60 solutions_root: Field<N>,
61 subdag_root: Field<N>,
62 metadata: Metadata<N>,
63 ) -> Result<Self> {
64 let header = Self {
66 previous_state_root,
67 transactions_root,
68 finalize_root,
69 ratifications_root,
70 solutions_root,
71 subdag_root,
72 metadata,
73 };
74 match header.is_valid() {
76 true => Ok(header),
77 false => bail!("Invalid block header: {:?}", header),
78 }
79 }
80
81 pub fn is_valid(&self) -> bool {
83 match self.height() == 0u32 {
84 true => self.is_genesis(),
85 false => {
86 *self.previous_state_root != Field::zero()
88 && self.transactions_root != Field::zero()
90 && self.finalize_root != Field::zero()
92 && self.ratifications_root != Field::zero()
94 && self.metadata.is_valid()
96 }
97 }
98 }
99
100 pub const fn previous_state_root(&self) -> N::StateRoot {
102 self.previous_state_root
103 }
104
105 pub const fn transactions_root(&self) -> Field<N> {
107 self.transactions_root
108 }
109
110 pub const fn finalize_root(&self) -> Field<N> {
112 self.finalize_root
113 }
114
115 pub const fn ratifications_root(&self) -> Field<N> {
117 self.ratifications_root
118 }
119
120 pub const fn solutions_root(&self) -> Field<N> {
122 self.solutions_root
123 }
124
125 pub const fn subdag_root(&self) -> Field<N> {
127 self.subdag_root
128 }
129
130 pub const fn metadata(&self) -> &Metadata<N> {
132 &self.metadata
133 }
134
135 pub const fn network(&self) -> u16 {
137 self.metadata.network()
138 }
139
140 pub const fn round(&self) -> u64 {
142 self.metadata.round()
143 }
144
145 pub const fn height(&self) -> u32 {
147 self.metadata.height()
148 }
149
150 pub const fn cumulative_weight(&self) -> u128 {
152 self.metadata.cumulative_weight()
153 }
154
155 pub const fn cumulative_proof_target(&self) -> u128 {
157 self.metadata.cumulative_proof_target()
158 }
159
160 pub const fn coinbase_target(&self) -> u64 {
162 self.metadata.coinbase_target()
163 }
164
165 pub const fn proof_target(&self) -> u64 {
167 self.metadata.proof_target()
168 }
169
170 pub const fn last_coinbase_target(&self) -> u64 {
172 self.metadata.last_coinbase_target()
173 }
174
175 pub const fn last_coinbase_timestamp(&self) -> i64 {
177 self.metadata.last_coinbase_timestamp()
178 }
179
180 pub const fn timestamp(&self) -> i64 {
182 self.metadata.timestamp()
183 }
184}
185
186#[cfg(test)]
187pub mod test_helpers {
188 use super::*;
189
190 type CurrentNetwork = console::network::MainnetV0;
191
192 pub(crate) fn sample_block_header(rng: &mut TestRng) -> Header<CurrentNetwork> {
194 *crate::test_helpers::sample_genesis_block(rng).header()
195 }
196}