1#![allow(unused_doc_comments)] #![allow(unused_variables, unused_assignments, dead_code)] #![allow(
46 clippy::too_many_arguments, clippy::type_complexity, clippy::large_enum_variant, )]
50
51pub mod script;
52pub mod transaction;
53pub mod transaction_hash;
54
55use blvm_spec_lock::spec_locked;
56#[cfg(all(feature = "production", feature = "benchmarking"))]
57pub use config::{reset_assume_valid_height, set_assume_valid_height};
58#[cfg(feature = "production")]
59pub use script::batch_verify_signatures;
60#[cfg(all(feature = "production", feature = "benchmarking"))]
61pub use script::{
62 clear_all_caches, clear_hash_cache, clear_script_cache, clear_stack_pool, disable_caching,
63 reset_benchmarking_state,
64};
65#[cfg(all(feature = "production", feature = "benchmarking"))]
66pub use transaction_hash::clear_sighash_templates;
67
68pub use blvm_primitives::constants;
70pub use blvm_primitives::crypto;
71pub use blvm_primitives::opcodes;
72pub use blvm_primitives::serialization;
73pub use blvm_primitives::{error, types};
74pub use blvm_primitives::{tx_inputs, tx_outputs};
75pub use constants::*;
76pub use error::ConsensusError;
77pub use types::*;
78
79pub mod orange_paper_constants {
81 pub use crate::constants::{C, H, L_ELEMENT, L_OPS, L_SCRIPT, L_STACK, M_MAX, R, S_MAX, W_MAX};
82}
83
84pub mod orange_paper_property_helpers;
85
86pub mod config;
87
88pub mod activation;
89pub mod bip113;
90#[cfg(feature = "ctv")]
91pub mod bip119;
92#[cfg(any(feature = "csfs", feature = "production"))]
93pub mod bip348;
94pub mod bip_validation;
95pub mod block;
96#[cfg(all(feature = "production", feature = "rayon"))]
97pub mod checkqueue;
98pub mod economic;
99pub mod locktime;
100pub mod mempool;
101pub mod mining;
102pub mod optimizations;
103pub mod pow;
104pub mod reorganization;
105#[cfg(all(feature = "production", feature = "rayon"))]
106pub(crate) mod script_exec_cache;
107pub mod secp256k1_backend;
108pub mod segwit;
109pub mod sequence_locks;
110pub mod sigop;
111pub mod taproot;
112pub mod utxo_overlay;
113pub mod version_bits;
114pub mod witness;
115
116pub mod test_utils;
119
120#[cfg(feature = "profile")]
121pub mod profile_log;
122#[cfg(all(feature = "production", feature = "profile"))]
123pub mod script_profile;
124
125#[derive(Debug, Clone, Copy, Default)]
130pub struct ConsensusProof;
131
132impl ConsensusProof {
133 pub fn new() -> Self {
135 Self
136 }
137
138 #[spec_locked("5.1")]
140 pub fn validate_transaction(
141 &self,
142 tx: &types::Transaction,
143 ) -> error::Result<types::ValidationResult> {
144 transaction::check_transaction(tx)
145 }
146
147 #[spec_locked("5.1")]
149 pub fn validate_tx_inputs(
150 &self,
151 tx: &types::Transaction,
152 utxo_set: &types::UtxoSet,
153 height: types::Natural,
154 ) -> error::Result<(types::ValidationResult, types::Integer)> {
155 transaction::check_tx_inputs(tx, utxo_set, height)
156 }
157
158 #[spec_locked("5.3")]
160 pub fn validate_block(
161 &self,
162 block: &types::Block,
163 utxo_set: types::UtxoSet,
164 height: types::Natural,
165 ) -> error::Result<(types::ValidationResult, types::UtxoSet)> {
166 let witnesses: Vec<Vec<segwit::Witness>> =
168 block.transactions.iter().map(|_| Vec::new()).collect();
169 let network_time = std::time::SystemTime::now()
170 .duration_since(std::time::UNIX_EPOCH)
171 .unwrap()
172 .as_secs();
173 let context = block::BlockValidationContext::from_connect_block_ibd_args(
174 None::<&[types::BlockHeader]>,
175 network_time,
176 types::Network::Mainnet,
177 None,
178 None,
179 );
180 let (result, new_utxo_set, _undo_log) =
181 block::connect_block(block, &witnesses, utxo_set, height, &context)?;
182 Ok((result, new_utxo_set))
183 }
184
185 #[spec_locked("5.3")]
187 pub fn validate_block_with_time_context(
188 &self,
189 block: &types::Block,
190 witnesses: &[Vec<segwit::Witness>],
191 utxo_set: types::UtxoSet,
192 height: types::Natural,
193 time_context: Option<types::TimeContext>,
194 network: types::Network,
195 ) -> error::Result<(types::ValidationResult, types::UtxoSet)> {
196 let context = block::BlockValidationContext::from_time_context_and_network(
197 time_context,
198 network,
199 None,
200 );
201 let (result, new_utxo_set, _undo_log) =
202 block::connect_block(block, witnesses, utxo_set, height, &context)?;
203 Ok((result, new_utxo_set))
204 }
205
206 #[spec_locked("5.2")]
208 pub fn verify_script(
209 &self,
210 script_sig: &types::ByteString,
211 script_pubkey: &types::ByteString,
212 witness: Option<&types::ByteString>,
213 flags: u32,
214 ) -> error::Result<bool> {
215 script::verify_script(script_sig, script_pubkey, witness, flags)
216 }
217
218 #[spec_locked("7.2")]
220 pub fn check_proof_of_work(&self, header: &types::BlockHeader) -> error::Result<bool> {
221 pow::check_proof_of_work(header)
222 }
223
224 #[spec_locked("6.1")]
226 pub fn get_block_subsidy(&self, height: types::Natural) -> types::Integer {
227 economic::get_block_subsidy(height)
228 }
229
230 #[spec_locked("6.2")]
232 pub fn total_supply(&self, height: types::Natural) -> types::Integer {
233 economic::total_supply(height)
234 }
235
236 #[spec_locked("7.1")]
238 pub fn get_next_work_required(
239 &self,
240 current_header: &types::BlockHeader,
241 prev_headers: &[types::BlockHeader],
242 ) -> error::Result<types::Natural> {
243 pow::get_next_work_required(current_header, prev_headers)
244 }
245
246 #[spec_locked("9.1")]
248 pub fn accept_to_memory_pool(
249 &self,
250 tx: &types::Transaction,
251 utxo_set: &types::UtxoSet,
252 mempool: &mempool::Mempool,
253 height: types::Natural,
254 time_context: Option<types::TimeContext>,
255 ) -> error::Result<mempool::MempoolResult> {
256 mempool::accept_to_memory_pool(tx, None, utxo_set, mempool, height, time_context)
257 }
258
259 #[spec_locked("9.2")]
261 pub fn is_standard_tx(&self, tx: &types::Transaction) -> error::Result<bool> {
262 mempool::is_standard_tx(tx)
263 }
264
265 #[spec_locked("9.3")]
267 pub fn replacement_checks(
268 &self,
269 new_tx: &types::Transaction,
270 existing_tx: &types::Transaction,
271 utxo_set: &types::UtxoSet,
272 mempool: &mempool::Mempool,
273 ) -> error::Result<bool> {
274 mempool::replacement_checks(new_tx, existing_tx, utxo_set, mempool)
275 }
276
277 #[allow(clippy::too_many_arguments)]
279 #[spec_locked("12.1")]
280 pub fn create_new_block(
281 &self,
282 utxo_set: &types::UtxoSet,
283 mempool_txs: &[types::Transaction],
284 height: types::Natural,
285 prev_header: &types::BlockHeader,
286 prev_headers: &[types::BlockHeader],
287 coinbase_script: &types::ByteString,
288 coinbase_address: &types::ByteString,
289 ) -> error::Result<types::Block> {
290 mining::create_new_block(
291 utxo_set,
292 mempool_txs,
293 height,
294 prev_header,
295 prev_headers,
296 coinbase_script,
297 coinbase_address,
298 )
299 }
300
301 #[spec_locked("12.3")]
303 pub fn mine_block(
304 &self,
305 block: types::Block,
306 max_attempts: types::Natural,
307 ) -> error::Result<(types::Block, mining::MiningResult)> {
308 mining::mine_block(block, max_attempts)
309 }
310
311 #[allow(clippy::too_many_arguments)]
313 #[spec_locked("12.1")]
314 pub fn create_block_template(
315 &self,
316 utxo_set: &types::UtxoSet,
317 mempool_txs: &[types::Transaction],
318 height: types::Natural,
319 prev_header: &types::BlockHeader,
320 prev_headers: &[types::BlockHeader],
321 coinbase_script: &types::ByteString,
322 coinbase_address: &types::ByteString,
323 ) -> error::Result<mining::BlockTemplate> {
324 mining::create_block_template(
325 utxo_set,
326 mempool_txs,
327 height,
328 prev_header,
329 prev_headers,
330 coinbase_script,
331 coinbase_address,
332 )
333 }
334
335 #[spec_locked("11.3")]
337 pub fn reorganize_chain(
338 &self,
339 new_chain: &[types::Block],
340 current_chain: &[types::Block],
341 current_utxo_set: types::UtxoSet,
342 current_height: types::Natural,
343 network: types::Network,
344 ) -> error::Result<reorganization::ReorganizationResult> {
345 reorganization::reorganize_chain(
346 new_chain,
347 current_chain,
348 current_utxo_set,
349 current_height,
350 network,
351 )
352 }
353
354 #[spec_locked("11.3")]
356 pub fn should_reorganize(
357 &self,
358 new_chain: &[types::Block],
359 current_chain: &[types::Block],
360 ) -> error::Result<bool> {
361 reorganization::should_reorganize(new_chain, current_chain)
362 }
363
364 #[spec_locked("11.1.1")]
366 pub fn calculate_transaction_weight(
367 &self,
368 tx: &types::Transaction,
369 witness: Option<&segwit::Witness>,
370 ) -> error::Result<types::Natural> {
371 segwit::calculate_transaction_weight(tx, witness)
372 }
373
374 #[spec_locked("11.1.7")]
376 pub fn validate_segwit_block(
377 &self,
378 block: &types::Block,
379 witnesses: &[segwit::Witness],
380 max_block_weight: types::Natural,
381 ) -> error::Result<bool> {
382 segwit::validate_segwit_block(block, witnesses, max_block_weight)
383 }
384
385 #[spec_locked("11.2.5")]
387 pub fn validate_taproot_transaction(
388 &self,
389 tx: &types::Transaction,
390 witness: Option<&segwit::Witness>,
391 ) -> error::Result<bool> {
392 taproot::validate_taproot_transaction(tx, witness)
393 }
394
395 #[spec_locked("11.2.1")]
397 pub fn is_taproot_output(&self, output: &types::TransactionOutput) -> bool {
398 taproot::is_taproot_output(output)
399 }
400}
401
402#[cfg(test)]
403mod tests {
404 use super::*;
405 use crate::transaction::check_transaction;
406 use crate::types::Transaction;
407
408 #[test]
409 fn test_validate_transaction() {
410 let tx = Transaction {
411 version: 1,
412 inputs: vec![].into(),
413 outputs: vec![].into(),
414 lock_time: 0,
415 };
416 let result = check_transaction(&tx);
417 assert!(result.is_ok());
418 }
419}