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
84#[doc(hidden)]
88pub mod orange_paper_property_helpers;
89
90pub mod config;
91
92pub mod activation;
93pub mod bip113;
94#[cfg(feature = "ctv")]
95pub mod bip119;
96#[cfg(any(feature = "csfs", feature = "production"))]
97pub mod bip348;
98pub mod bip_validation;
99pub mod block;
100#[cfg(all(feature = "production", feature = "rayon"))]
101pub mod checkqueue;
102pub mod economic;
103pub mod locktime;
104pub mod mempool;
105pub mod mining;
106pub mod optimizations;
107pub mod pow;
108pub mod reorganization;
109#[cfg(all(feature = "production", feature = "rayon"))]
110pub(crate) mod script_exec_cache;
111pub mod secp256k1_backend;
112pub mod segwit;
113pub mod sequence_locks;
114pub mod sigop;
115pub mod taproot;
116pub mod utxo_overlay;
117pub mod version_bits;
118pub mod witness;
119
120pub mod test_utils;
123
124#[cfg(feature = "profile")]
125pub mod profile_log;
126#[cfg(all(feature = "production", feature = "profile"))]
127pub mod script_profile;
128
129#[derive(Debug, Clone, Copy, Default)]
134pub struct ConsensusProof;
135
136impl ConsensusProof {
137 pub fn new() -> Self {
139 Self
140 }
141
142 #[spec_locked("5.1", "CheckTransaction")]
144 pub fn validate_transaction(
145 &self,
146 tx: &types::Transaction,
147 ) -> error::Result<types::ValidationResult> {
148 transaction::check_transaction(tx)
149 }
150
151 #[spec_locked("5.1", "CheckTxInputs")]
153 pub fn validate_tx_inputs(
154 &self,
155 tx: &types::Transaction,
156 utxo_set: &types::UtxoSet,
157 height: types::Natural,
158 ) -> error::Result<(types::ValidationResult, types::Integer)> {
159 transaction::check_tx_inputs(tx, utxo_set, height)
160 }
161
162 #[spec_locked("5.3", "ConnectBlock")]
164 pub fn validate_block(
165 &self,
166 block: &types::Block,
167 utxo_set: types::UtxoSet,
168 height: types::Natural,
169 ) -> error::Result<(types::ValidationResult, types::UtxoSet)> {
170 let witnesses: Vec<Vec<segwit::Witness>> =
172 block.transactions.iter().map(|_| Vec::new()).collect();
173 let network_time = std::time::SystemTime::now()
177 .duration_since(std::time::UNIX_EPOCH)
178 .unwrap_or(std::time::Duration::ZERO)
179 .as_secs();
180 let context = block::block_validation_context_for_connect_ibd(
181 None::<&[types::BlockHeader]>,
182 network_time,
183 types::Network::Mainnet,
184 );
185 let (result, new_utxo_set, _undo_log) =
186 block::connect_block(block, &witnesses, utxo_set, height, &context)?;
187 Ok((result, new_utxo_set))
188 }
189
190 #[spec_locked("5.3", "ConnectBlock")]
192 pub fn validate_block_with_time_context(
193 &self,
194 block: &types::Block,
195 witnesses: &[Vec<segwit::Witness>],
196 utxo_set: types::UtxoSet,
197 height: types::Natural,
198 time_context: Option<types::TimeContext>,
199 network: types::Network,
200 ) -> error::Result<(types::ValidationResult, types::UtxoSet)> {
201 let context = block::BlockValidationContext::from_time_context_and_network(
202 time_context,
203 network,
204 None,
205 );
206 let (result, new_utxo_set, _undo_log) =
207 block::connect_block(block, witnesses, utxo_set, height, &context)?;
208 Ok((result, new_utxo_set))
209 }
210
211 #[spec_locked("5.2", "VerifyScript")]
213 pub fn verify_script(
214 &self,
215 script_sig: &types::ByteString,
216 script_pubkey: &types::ByteString,
217 witness: Option<&types::ByteString>,
218 flags: u32,
219 ) -> error::Result<bool> {
220 script::verify_script(script_sig, script_pubkey, witness, flags)
221 }
222
223 #[spec_locked("7.2", "CheckProofOfWork")]
225 pub fn check_proof_of_work(&self, header: &types::BlockHeader) -> error::Result<bool> {
226 pow::check_proof_of_work(header)
227 }
228
229 #[spec_locked("6.1", "GetBlockSubsidy")]
231 pub fn get_block_subsidy(&self, height: types::Natural) -> types::Integer {
232 economic::get_block_subsidy(height)
233 }
234
235 #[spec_locked("6.2", "TotalSupply")]
237 pub fn total_supply(&self, height: types::Natural) -> types::Integer {
238 economic::total_supply(height)
239 }
240
241 #[spec_locked("7.1", "GetNextWorkRequired")]
243 pub fn get_next_work_required(
244 &self,
245 current_header: &types::BlockHeader,
246 prev_headers: &[types::BlockHeader],
247 ) -> error::Result<types::Natural> {
248 pow::get_next_work_required(current_header, prev_headers)
249 }
250
251 #[spec_locked("9.1", "AcceptToMemoryPool")]
253 pub fn accept_to_memory_pool(
254 &self,
255 tx: &types::Transaction,
256 utxo_set: &types::UtxoSet,
257 mempool: &mempool::Mempool,
258 height: types::Natural,
259 time_context: Option<types::TimeContext>,
260 ) -> error::Result<mempool::MempoolResult> {
261 mempool::accept_to_memory_pool(tx, None, utxo_set, mempool, height, time_context)
262 }
263
264 #[spec_locked("9.2", "IsStandardTx")]
266 pub fn is_standard_tx(&self, tx: &types::Transaction) -> error::Result<bool> {
267 mempool::is_standard_tx(tx)
268 }
269
270 #[spec_locked("9.3", "ReplacementChecks")]
272 pub fn replacement_checks(
273 &self,
274 new_tx: &types::Transaction,
275 existing_tx: &types::Transaction,
276 utxo_set: &types::UtxoSet,
277 mempool: &mempool::Mempool,
278 ) -> error::Result<bool> {
279 mempool::replacement_checks(new_tx, existing_tx, utxo_set, mempool)
280 }
281
282 #[allow(clippy::too_many_arguments)]
284 #[spec_locked("12.1", "CreateNewBlock")]
285 pub fn create_new_block(
286 &self,
287 utxo_set: &types::UtxoSet,
288 mempool_txs: &[types::Transaction],
289 height: types::Natural,
290 prev_header: &types::BlockHeader,
291 prev_headers: &[types::BlockHeader],
292 coinbase_script: &types::ByteString,
293 coinbase_address: &types::ByteString,
294 ) -> error::Result<types::Block> {
295 mining::create_new_block(
296 utxo_set,
297 mempool_txs,
298 height,
299 prev_header,
300 prev_headers,
301 coinbase_script,
302 coinbase_address,
303 )
304 }
305
306 #[spec_locked("12.3", "MineBlock")]
308 pub fn mine_block(
309 &self,
310 block: types::Block,
311 max_attempts: types::Natural,
312 ) -> error::Result<(types::Block, mining::MiningResult)> {
313 mining::mine_block(block, max_attempts)
314 }
315
316 #[allow(clippy::too_many_arguments)]
318 #[spec_locked("12.4", "BlockTemplate")]
319 pub fn create_block_template(
320 &self,
321 utxo_set: &types::UtxoSet,
322 mempool_txs: &[types::Transaction],
323 height: types::Natural,
324 prev_header: &types::BlockHeader,
325 prev_headers: &[types::BlockHeader],
326 coinbase_script: &types::ByteString,
327 coinbase_address: &types::ByteString,
328 ) -> error::Result<mining::BlockTemplate> {
329 mining::create_block_template(
330 utxo_set,
331 mempool_txs,
332 height,
333 prev_header,
334 prev_headers,
335 coinbase_script,
336 coinbase_address,
337 )
338 }
339
340 #[spec_locked("11.3")]
342 pub fn reorganize_chain(
343 &self,
344 new_chain: &[types::Block],
345 current_chain: &[types::Block],
346 current_utxo_set: types::UtxoSet,
347 current_height: types::Natural,
348 network: types::Network,
349 ) -> error::Result<reorganization::ReorganizationResult> {
350 reorganization::reorganize_chain(
351 new_chain,
352 current_chain,
353 current_utxo_set,
354 current_height,
355 network,
356 )
357 }
358
359 #[spec_locked("11.3", "ShouldReorganize")]
361 pub fn should_reorganize(
362 &self,
363 new_chain: &[types::Block],
364 current_chain: &[types::Block],
365 ) -> error::Result<bool> {
366 reorganization::should_reorganize(new_chain, current_chain)
367 }
368
369 #[spec_locked("11.1.1", "CalculateTransactionWeight")]
371 pub fn calculate_transaction_weight(
372 &self,
373 tx: &types::Transaction,
374 witness: Option<&segwit::Witness>,
375 ) -> error::Result<types::Natural> {
376 segwit::calculate_transaction_weight(tx, witness)
377 }
378
379 #[spec_locked("11.1.7", "ValidateSegWitBlock")]
381 pub fn validate_segwit_block(
382 &self,
383 block: &types::Block,
384 witnesses: &[segwit::Witness],
385 max_block_weight: types::Natural,
386 ) -> error::Result<bool> {
387 segwit::validate_segwit_block(block, witnesses, max_block_weight)
388 }
389
390 #[spec_locked("11.2.5", "ValidateTaprootTransaction")]
392 pub fn validate_taproot_transaction(
393 &self,
394 tx: &types::Transaction,
395 witness: Option<&segwit::Witness>,
396 ) -> error::Result<bool> {
397 taproot::validate_taproot_transaction(tx, witness)
398 }
399
400 #[spec_locked("11.2.1", "IsTaprootOutput")]
402 pub fn is_taproot_output(&self, output: &types::TransactionOutput) -> bool {
403 taproot::is_taproot_output(output)
404 }
405}
406
407#[cfg(test)]
408mod tests {
409 use crate::transaction::check_transaction;
410 use crate::types::Transaction;
411
412 #[test]
413 fn test_validate_transaction() {
414 let tx = Transaction {
415 version: 1,
416 inputs: vec![].into(),
417 outputs: vec![].into(),
418 lock_time: 0,
419 };
420 let result = check_transaction(&tx);
421 assert!(result.is_ok());
422 }
423}