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(crate) mod spec_witnesses;
116pub mod taproot;
117pub mod utxo_overlay;
118pub mod version_bits;
119pub mod witness;
120
121pub mod test_utils;
124
125#[cfg(feature = "profile")]
126pub mod profile_log;
127#[cfg(all(feature = "production", feature = "profile"))]
128pub mod script_profile;
129
130#[derive(Debug, Clone, Copy, Default)]
135pub struct ConsensusProof;
136
137impl ConsensusProof {
138 pub fn new() -> Self {
140 Self
141 }
142
143 #[spec_locked("5.1", "CheckTransaction")]
145 #[blvm_spec_lock::ensures(result == true || result == false)]
146 pub fn validate_transaction(
147 &self,
148 tx: &types::Transaction,
149 ) -> error::Result<types::ValidationResult> {
150 transaction::check_transaction(tx)
151 }
152
153 #[spec_locked("5.1", "CheckTxInputs")]
155 #[blvm_spec_lock::ensures(result_0 == true || result_0 == false)]
156 pub fn validate_tx_inputs(
157 &self,
158 tx: &types::Transaction,
159 utxo_set: &types::UtxoSet,
160 height: types::Natural,
161 ) -> error::Result<(types::ValidationResult, types::Integer)> {
162 transaction::check_tx_inputs(tx, utxo_set, height)
163 }
164
165 #[spec_locked("5.3", "ConnectBlock")]
167 #[blvm_spec_lock::ensures(result_0 == true || result_0 == false)]
168 pub fn validate_block(
169 &self,
170 block: &types::Block,
171 utxo_set: types::UtxoSet,
172 height: types::Natural,
173 ) -> error::Result<(types::ValidationResult, types::UtxoSet)> {
174 let witnesses: Vec<Vec<segwit::Witness>> =
176 block.transactions.iter().map(|_| Vec::new()).collect();
177 let network_time = std::time::SystemTime::now()
181 .duration_since(std::time::UNIX_EPOCH)
182 .unwrap_or(std::time::Duration::ZERO)
183 .as_secs();
184 let context = block::block_validation_context_for_connect_ibd(
185 None::<&[types::BlockHeader]>,
186 network_time,
187 types::Network::Mainnet,
188 );
189 let (result, new_utxo_set, _undo_log) =
190 block::connect_block(block, &witnesses, utxo_set, height, &context)?;
191 Ok((result, new_utxo_set))
192 }
193
194 #[spec_locked("5.3", "ConnectBlock")]
196 #[blvm_spec_lock::ensures(result_0 == true || result_0 == false)]
197 pub fn validate_block_with_time_context(
198 &self,
199 block: &types::Block,
200 witnesses: &[Vec<segwit::Witness>],
201 utxo_set: types::UtxoSet,
202 height: types::Natural,
203 time_context: Option<types::TimeContext>,
204 network: types::Network,
205 ) -> error::Result<(types::ValidationResult, types::UtxoSet)> {
206 let context = block::BlockValidationContext::from_time_context_and_network(
207 time_context,
208 network,
209 None,
210 );
211 let (result, new_utxo_set, _undo_log) =
212 block::connect_block(block, witnesses, utxo_set, height, &context)?;
213 Ok((result, new_utxo_set))
214 }
215
216 #[spec_locked("5.2", "VerifyScript")]
218 #[blvm_spec_lock::ensures(result == true || result == false)]
219 pub fn verify_script(
220 &self,
221 script_sig: &types::ByteString,
222 script_pubkey: &types::ByteString,
223 witness: Option<&types::ByteString>,
224 flags: u32,
225 ) -> error::Result<bool> {
226 script::verify_script(script_sig, script_pubkey, witness, flags)
227 }
228
229 #[spec_locked("7.2", "CheckProofOfWork")]
231 #[blvm_spec_lock::ensures(result == true || result == false)]
232 pub fn check_proof_of_work(&self, header: &types::BlockHeader) -> error::Result<bool> {
233 pow::check_proof_of_work(header)
234 }
235
236 #[spec_locked("6.1", "GetBlockSubsidy")]
238 #[blvm_spec_lock::ensures(result >= 0)]
239 #[blvm_spec_lock::axiom(result <= INITIAL_SUBSIDY)]
240 pub fn get_block_subsidy(&self, height: types::Natural) -> types::Integer {
241 economic::get_block_subsidy(height)
242 }
243
244 #[spec_locked("6.2", "TotalSupply")]
246 #[blvm_spec_lock::ensures(result >= 0)]
247 pub fn total_supply(&self, height: types::Natural) -> types::Integer {
248 economic::total_supply(height)
249 }
250
251 #[spec_locked("7.1", "GetNextWorkRequired")]
253 #[blvm_spec_lock::ensures(result >= 0)]
254 pub fn get_next_work_required(
255 &self,
256 current_header: &types::BlockHeader,
257 prev_headers: &[types::BlockHeader],
258 ) -> error::Result<types::Natural> {
259 pow::get_next_work_required(current_header, prev_headers)
260 }
261
262 #[spec_locked("9.1", "AcceptToMemoryPool")]
264 #[blvm_spec_lock::ensures(result == true || result == false)]
265 pub fn accept_to_memory_pool(
266 &self,
267 tx: &types::Transaction,
268 utxo_set: &types::UtxoSet,
269 mempool: &mempool::Mempool,
270 height: types::Natural,
271 time_context: Option<types::TimeContext>,
272 ) -> error::Result<mempool::MempoolResult> {
273 mempool::accept_to_memory_pool(tx, None, utxo_set, mempool, height, time_context)
274 }
275
276 #[spec_locked("9.2", "IsStandardTx")]
278 #[blvm_spec_lock::ensures(result == true || result == false)]
279 pub fn is_standard_tx(&self, tx: &types::Transaction) -> error::Result<bool> {
280 mempool::is_standard_tx(tx)
281 }
282
283 #[spec_locked("9.3", "ReplacementChecks")]
285 #[blvm_spec_lock::ensures(result == true || result == false)]
286 pub fn replacement_checks(
287 &self,
288 new_tx: &types::Transaction,
289 existing_tx: &types::Transaction,
290 utxo_set: &types::UtxoSet,
291 mempool: &mempool::Mempool,
292 ) -> error::Result<bool> {
293 mempool::replacement_checks(new_tx, existing_tx, utxo_set, mempool)
294 }
295
296 #[allow(clippy::too_many_arguments)]
298 #[spec_locked("12.1", "CreateNewBlock")]
299 #[blvm_spec_lock::ensures(result >= 0)]
300 pub fn create_new_block(
301 &self,
302 utxo_set: &types::UtxoSet,
303 mempool_txs: &[types::Transaction],
304 height: types::Natural,
305 prev_header: &types::BlockHeader,
306 prev_headers: &[types::BlockHeader],
307 coinbase_script: &types::ByteString,
308 coinbase_address: &types::ByteString,
309 ) -> error::Result<types::Block> {
310 mining::create_new_block(
311 utxo_set,
312 mempool_txs,
313 height,
314 prev_header,
315 prev_headers,
316 coinbase_script,
317 coinbase_address,
318 )
319 }
320
321 #[spec_locked("12.3", "MineBlock")]
323 #[blvm_spec_lock::ensures(result_0 >= 0)]
324 pub fn mine_block(
325 &self,
326 block: types::Block,
327 max_attempts: types::Natural,
328 ) -> error::Result<(types::Block, mining::MiningResult)> {
329 mining::mine_block(block, max_attempts)
330 }
331
332 #[allow(clippy::too_many_arguments)]
334 #[spec_locked("12.4", "BlockTemplate")]
335 #[blvm_spec_lock::ensures(result >= 0)]
336 pub fn create_block_template(
337 &self,
338 utxo_set: &types::UtxoSet,
339 mempool_txs: &[types::Transaction],
340 height: types::Natural,
341 prev_header: &types::BlockHeader,
342 prev_headers: &[types::BlockHeader],
343 coinbase_script: &types::ByteString,
344 coinbase_address: &types::ByteString,
345 ) -> error::Result<mining::BlockTemplate> {
346 mining::create_block_template(
347 utxo_set,
348 mempool_txs,
349 height,
350 prev_header,
351 prev_headers,
352 coinbase_script,
353 coinbase_address,
354 )
355 }
356
357 #[spec_locked("11.3")]
359 #[blvm_spec_lock::ensures(result >= 0)]
360 pub fn reorganize_chain(
361 &self,
362 new_chain: &[types::Block],
363 current_chain: &[types::Block],
364 current_utxo_set: types::UtxoSet,
365 current_height: types::Natural,
366 network: types::Network,
367 ) -> error::Result<reorganization::ReorganizationResult> {
368 reorganization::reorganize_chain(
369 new_chain,
370 current_chain,
371 current_utxo_set,
372 current_height,
373 network,
374 )
375 }
376
377 #[spec_locked("11.3", "ShouldReorganize")]
379 #[blvm_spec_lock::ensures(result == true || result == false)]
380 pub fn should_reorganize(
381 &self,
382 new_chain: &[types::Block],
383 current_chain: &[types::Block],
384 ) -> error::Result<bool> {
385 reorganization::should_reorganize(new_chain, current_chain)
386 }
387
388 #[spec_locked("11.1.1", "CalculateTransactionWeight")]
390 #[blvm_spec_lock::ensures(result >= 0)]
391 pub fn calculate_transaction_weight(
392 &self,
393 tx: &types::Transaction,
394 witness: Option<&segwit::Witness>,
395 ) -> error::Result<types::Natural> {
396 segwit::calculate_transaction_weight(tx, witness)
397 }
398
399 #[spec_locked("11.1.7", "ValidateSegWitBlock")]
401 #[blvm_spec_lock::ensures(result == true || result == false)]
402 pub fn validate_segwit_block(
403 &self,
404 block: &types::Block,
405 witnesses: &[segwit::Witness],
406 max_block_weight: types::Natural,
407 ) -> error::Result<bool> {
408 segwit::validate_segwit_block(block, witnesses, max_block_weight)
409 }
410
411 #[spec_locked("11.2.5", "ValidateTaprootTransaction")]
413 #[blvm_spec_lock::ensures(result == true || result == false)]
414 pub fn validate_taproot_transaction(
415 &self,
416 tx: &types::Transaction,
417 witness: Option<&segwit::Witness>,
418 ) -> error::Result<bool> {
419 taproot::validate_taproot_transaction(tx, witness)
420 }
421
422 #[spec_locked("11.2.1", "IsTaprootOutput")]
424 #[blvm_spec_lock::ensures(result == true || result == false)]
425 pub fn is_taproot_output(&self, output: &types::TransactionOutput) -> bool {
426 taproot::is_taproot_output(output)
427 }
428}
429
430#[cfg(test)]
431mod tests {
432 use crate::transaction::check_transaction;
433 use crate::types::Transaction;
434
435 #[test]
436 fn test_validate_transaction() {
437 let tx = Transaction {
438 version: 1,
439 inputs: vec![].into(),
440 outputs: vec![].into(),
441 lock_time: 0,
442 };
443 let result = check_transaction(&tx);
444 assert!(result.is_ok());
445 }
446}