1use serde::{Deserialize, Serialize};
18
19pub use blvm_consensus::config::NetworkMessageLimits;
22pub use blvm_consensus::error::{ConsensusError, Result as ConsensusResult};
23pub use blvm_consensus::types::{
24 Block, BlockHeader, ByteString, Hash, Integer, Natural, OutPoint, Transaction,
25 TransactionInput, TransactionOutput, UtxoSet, ValidationResult, Witness, UTXO,
26};
27pub use blvm_consensus::ConsensusProof;
28
29#[cfg(all(feature = "production", feature = "benchmarking"))]
30pub use blvm_consensus::config::{reset_assume_valid_height, set_assume_valid_height};
31pub use blvm_consensus::{
33 BIP112_CSV_ACTIVATION_MAINNET, BIP112_CSV_ACTIVATION_REGTEST, BIP112_CSV_ACTIVATION_TESTNET,
34 GENESIS_BLOCK_HASH_INTERNAL, SEGWIT_ACTIVATION_MAINNET, SEGWIT_ACTIVATION_TESTNET,
35 TAPROOT_ACTIVATION_MAINNET, TAPROOT_ACTIVATION_TESTNET,
36};
37
38#[cfg(feature = "production")]
40pub use smallvec;
41#[cfg(feature = "production")]
43pub use lru;
44#[cfg(feature = "production")]
45pub use rayon;
46
47#[macro_export]
50macro_rules! profile_log {
51 ($($arg:tt)*) => {
52 ::blvm_consensus::profile_log!($($arg)*)
53 };
54}
55
56pub use error::{ProtocolError, Result};
58
59pub mod mempool {
61 pub use blvm_consensus::mempool::*;
62}
63pub mod segwit {
64 pub use blvm_consensus::segwit::*;
65}
66pub mod block {
67 pub use blvm_consensus::block::*;
68
69 use crate::types::{BlockHeader, Network};
70
71 #[inline]
75 pub fn block_validation_context_for_connect_ibd<H: AsRef<BlockHeader>>(
76 recent_headers: Option<&[H]>,
77 network_time: u64,
78 network: Network,
79 ) -> BlockValidationContext {
80 BlockValidationContext::from_connect_block_ibd_args(
81 recent_headers,
82 network_time,
83 network,
84 None,
85 None,
86 )
87 }
88}
89pub mod mining {
90 pub use blvm_consensus::mining::*;
91}
92pub mod pow {
93 pub use blvm_consensus::pow::*;
94}
95
96pub mod witness {
97 pub use blvm_consensus::witness::*;
98}
99
100pub mod crypto {
101 pub use blvm_consensus::crypto::*;
102}
103
104pub mod transaction {
105 pub use blvm_consensus::transaction::*;
106}
107
108pub mod script {
110 pub use blvm_consensus::script::*;
111}
112
113pub mod transaction_hash {
115 pub use blvm_consensus::transaction_hash::*;
116}
117
118#[cfg(feature = "production")]
120pub mod optimizations {
121 pub use blvm_consensus::optimizations::*;
122}
123
124pub mod constants {
126 pub use blvm_consensus::constants::*;
127}
128
129pub mod bip113 {
130 pub use blvm_consensus::bip113::*;
131}
132
133pub mod bip_validation {
134 pub use blvm_consensus::bip_validation::*;
135}
136
137pub mod utxo_overlay {
138 pub use blvm_consensus::utxo_overlay::*;
139}
140
141pub mod version_bits {
142 pub use blvm_consensus::version_bits::*;
143}
144
145pub mod activation {
146 pub use blvm_consensus::activation::*;
147}
148
149pub mod consensus_config {
151 pub use blvm_consensus::config::*;
152}
153
154#[cfg(feature = "test-utils")]
155pub mod test_utils {
156 pub use blvm_consensus::test_utils::*;
157}
158
159pub use blvm_consensus::opcodes;
161
162pub mod sigop {
163 pub use blvm_consensus::sigop::*;
164}
165
166#[cfg(feature = "utxo-commitments")]
167pub mod utxo_commitments;
168
169pub mod spam_filter;
171pub mod serialization {
172 pub use blvm_consensus::serialization::*;
173}
174pub mod commons;
175pub mod network;
176pub mod node_tcp;
178
179pub use node_tcp::{ProtocolMessage, TcpFramedParser};
180pub mod p2p_commands;
181pub mod p2p_frame;
182pub mod p2p_framing;
183pub mod service_flags;
184pub mod varint;
185
186#[cfg(all(
188 feature = "bip324",
189 any(target_arch = "x86_64", target_arch = "aarch64")
190))]
191pub mod v2_transport;
192
193pub use commons::{
195 BanListMessage,
196 FilterPreferences,
198 FilteredBlockMessage,
200 GetBanListMessage,
201 GetFilteredBlockMessage,
202 GetUTXOProofMessage,
204 GetUTXOSetMessage,
205 UTXOCommitment,
207 UTXOProofMessage,
208 UTXOSetMessage,
209};
210pub use config::{
211 ProtocolConfig, ProtocolFeaturesConfig, ProtocolValidationConfig, ServiceFlagsConfig,
212};
213pub use network::{BlockMessage, CompactBlockMessage, TxMessage};
214pub use service_flags::{commons as service_flags_commons, standard as service_flags_standard};
215pub mod wire;
217
218#[cfg(test)]
219mod bip155_serialization_tests;
220pub mod types {
221 pub use blvm_consensus::types::*;
222}
223#[cfg(feature = "production")]
225pub use blvm_consensus::tx_inputs;
226#[cfg(not(feature = "production"))]
227pub use blvm_consensus::tx_inputs;
228#[cfg(feature = "production")]
229pub use blvm_consensus::tx_outputs;
230#[cfg(not(feature = "production"))]
231pub use blvm_consensus::tx_outputs;
232pub mod error;
233
234pub use economic::EconomicParameters;
236pub use features::{ActivationMethod, FeatureActivation, FeatureContext, FeatureRegistry};
237
238pub mod config;
239pub mod economic;
240pub mod features;
241pub mod genesis;
242pub mod network_params;
243pub mod validation;
244pub mod variants;
245
246pub mod address; #[cfg(feature = "ctv")]
249pub mod bip119 {
250 pub use blvm_consensus::bip119::*;
251}
252pub mod bip152; pub mod bip157; pub mod bip158; pub mod payment; pub mod time;
257
258pub struct BitcoinProtocolEngine {
263 consensus: ConsensusProof,
264 protocol_version: ProtocolVersion,
265 network_params: NetworkParameters,
266 config: ProtocolConfig,
267}
268
269#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
271pub enum ProtocolVersion {
272 BitcoinV1,
274 Testnet3,
276 Regtest,
278}
279
280#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
282pub struct NetworkParameters {
283 pub magic_bytes: [u8; 4],
285 pub default_port: u16,
287 pub genesis_block: Block,
289 pub max_target: u32,
291 pub halving_interval: u64,
293 pub network_name: String,
295 pub is_testnet: bool,
297}
298
299impl BitcoinProtocolEngine {
300 pub fn new(version: ProtocolVersion) -> Result<Self> {
302 Self::with_config(version, ProtocolConfig::default())
303 }
304
305 pub fn with_config(version: ProtocolVersion, config: ProtocolConfig) -> Result<Self> {
307 let consensus = ConsensusProof::new();
308 let network_params = NetworkParameters::for_version(version)?;
309
310 Ok(BitcoinProtocolEngine {
311 consensus,
312 protocol_version: version,
313 network_params,
314 config,
315 })
316 }
317
318 pub fn get_config(&self) -> &ProtocolConfig {
320 &self.config
321 }
322
323 pub fn get_config_mut(&mut self) -> &mut ProtocolConfig {
325 &mut self.config
326 }
327
328 pub fn get_protocol_version(&self) -> ProtocolVersion {
330 self.protocol_version
331 }
332
333 pub fn get_network_params(&self) -> &NetworkParameters {
335 &self.network_params
336 }
337
338 pub fn validate_block(
340 &self,
341 block: &Block,
342 utxos: &UtxoSet,
343 height: u64,
344 ) -> Result<ValidationResult> {
345 let network = match self.protocol_version {
346 ProtocolVersion::BitcoinV1 => types::Network::Mainnet,
347 ProtocolVersion::Testnet3 => types::Network::Testnet,
348 ProtocolVersion::Regtest => types::Network::Regtest,
349 };
350 let witnesses: Vec<Vec<blvm_consensus::segwit::Witness>> = block
351 .transactions
352 .iter()
353 .map(|tx| tx.inputs.iter().map(|_| Vec::new()).collect())
354 .collect();
355 let (result, _) = self
356 .consensus
357 .validate_block_with_time_context(
358 block,
359 &witnesses,
360 utxos.clone(),
361 height,
362 None,
363 network,
364 )
365 .map_err(ProtocolError::from)?;
366 Ok(result)
367 }
368
369 pub fn validate_transaction(&self, tx: &Transaction) -> Result<ValidationResult> {
371 self.consensus
372 .validate_transaction(tx)
373 .map_err(ProtocolError::from)
374 }
375
376 pub fn validate_and_connect_block(
434 &self,
435 block: &Block,
436 witnesses: &[Vec<segwit::Witness>], utxos: &UtxoSet,
440 height: u64,
441 recent_headers: Option<&[BlockHeader]>,
442 context: &validation::ProtocolValidationContext,
443 ) -> Result<(ValidationResult, UtxoSet)> {
444 let protocol_result = self.validate_block_with_protocol(block, utxos, height, context)?;
446 if !matches!(protocol_result, ValidationResult::Valid) {
447 return Ok((protocol_result, utxos.clone()));
448 }
449
450 let network = match self.protocol_version {
453 ProtocolVersion::BitcoinV1 => types::Network::Mainnet,
454 ProtocolVersion::Testnet3 => types::Network::Testnet,
455 ProtocolVersion::Regtest => types::Network::Regtest,
456 };
457 let network_time = crate::time::current_timestamp();
458 let context = crate::block::block_validation_context_for_connect_ibd(
459 recent_headers,
460 network_time,
461 network,
462 );
463 let (result, new_utxo_set, _undo_log) = blvm_consensus::block::connect_block(
464 block,
465 witnesses,
466 utxos.clone(),
467 height,
468 &context,
469 )?;
470
471 Ok((result, new_utxo_set))
472 }
473
474 pub fn supports_feature(&self, feature: &str) -> bool {
476 match self.protocol_version {
477 ProtocolVersion::BitcoinV1 => {
478 matches!(feature, "segwit" | "taproot" | "rbf" | "ctv")
479 }
480 ProtocolVersion::Testnet3 => {
481 matches!(feature, "segwit" | "taproot" | "rbf" | "ctv")
482 }
483 ProtocolVersion::Regtest => {
484 matches!(
485 feature,
486 "segwit" | "taproot" | "rbf" | "ctv" | "fast_mining"
487 )
488 }
489 }
490 }
491
492 pub fn is_feature_active(&self, feature: &str, height: u64, timestamp: u64) -> bool {
494 let registry = features::FeatureRegistry::for_protocol(self.protocol_version);
495 registry.is_feature_active(feature, height, timestamp)
496 }
497
498 pub fn get_economic_parameters(&self) -> economic::EconomicParameters {
500 economic::EconomicParameters::for_protocol(self.protocol_version)
501 }
502
503 pub fn get_feature_registry(&self) -> features::FeatureRegistry {
505 features::FeatureRegistry::for_protocol(self.protocol_version)
506 }
507
508 pub fn feature_context(&self, height: u64, timestamp: u64) -> features::FeatureContext {
511 let registry = features::FeatureRegistry::for_protocol(self.protocol_version);
512 registry.create_context(height, timestamp)
513 }
514}
515
516impl NetworkParameters {
517 pub fn for_version(version: ProtocolVersion) -> Result<Self> {
519 match version {
520 ProtocolVersion::BitcoinV1 => Self::mainnet(),
521 ProtocolVersion::Testnet3 => Self::testnet(),
522 ProtocolVersion::Regtest => Self::regtest(),
523 }
524 }
525
526 pub fn mainnet() -> Result<Self> {
528 Ok(NetworkParameters {
529 magic_bytes: [0xf9, 0xbe, 0xb4, 0xd9], default_port: 8333,
531 genesis_block: genesis::mainnet_genesis(),
532 max_target: 0x1d00ffff,
533 halving_interval: 210000,
534 network_name: "mainnet".to_string(),
535 is_testnet: false,
536 })
537 }
538
539 pub fn testnet() -> Result<Self> {
541 Ok(NetworkParameters {
542 magic_bytes: [0x0b, 0x11, 0x09, 0x07], default_port: 18333,
544 genesis_block: genesis::testnet_genesis(),
545 max_target: 0x1d00ffff,
546 halving_interval: 210000,
547 network_name: "testnet".to_string(),
548 is_testnet: true,
549 })
550 }
551
552 pub fn regtest() -> Result<Self> {
554 Ok(NetworkParameters {
555 magic_bytes: [0xfa, 0xbf, 0xb5, 0xda], default_port: 18444,
557 genesis_block: genesis::regtest_genesis(),
558 max_target: 0x207fffff, halving_interval: 150, network_name: "regtest".to_string(),
561 is_testnet: true,
562 })
563 }
564}
565
566#[cfg(test)]
567mod tests {
568 use super::*;
569 use blvm_consensus::types::{BlockHeader, OutPoint, TransactionInput, TransactionOutput};
570
571 #[test]
572 fn test_blvm_protocol_creation() {
573 let engine = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
574 assert_eq!(engine.get_protocol_version(), ProtocolVersion::BitcoinV1);
575 assert_eq!(engine.get_network_params().network_name, "mainnet");
576 }
577
578 #[test]
579 fn test_blvm_protocol_creation_all_variants() {
580 let mainnet = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
582 assert_eq!(mainnet.get_protocol_version(), ProtocolVersion::BitcoinV1);
583 assert_eq!(mainnet.get_network_params().network_name, "mainnet");
584 assert!(!mainnet.get_network_params().is_testnet);
585
586 let testnet = BitcoinProtocolEngine::new(ProtocolVersion::Testnet3).unwrap();
588 assert_eq!(testnet.get_protocol_version(), ProtocolVersion::Testnet3);
589 assert_eq!(testnet.get_network_params().network_name, "testnet");
590 assert!(testnet.get_network_params().is_testnet);
591
592 let regtest = BitcoinProtocolEngine::new(ProtocolVersion::Regtest).unwrap();
594 assert_eq!(regtest.get_protocol_version(), ProtocolVersion::Regtest);
595 assert_eq!(regtest.get_network_params().network_name, "regtest");
596 assert!(regtest.get_network_params().is_testnet);
597 }
598
599 #[test]
600 fn test_network_parameters() {
601 let mainnet = NetworkParameters::mainnet().unwrap();
602 assert_eq!(mainnet.magic_bytes, [0xf9, 0xbe, 0xb4, 0xd9]);
603 assert_eq!(mainnet.default_port, 8333);
604 assert!(!mainnet.is_testnet);
605
606 let testnet = NetworkParameters::testnet().unwrap();
607 assert_eq!(testnet.magic_bytes, [0x0b, 0x11, 0x09, 0x07]);
608 assert_eq!(testnet.default_port, 18333);
609 assert!(testnet.is_testnet);
610
611 let regtest = NetworkParameters::regtest().unwrap();
612 assert_eq!(regtest.magic_bytes, [0xfa, 0xbf, 0xb5, 0xda]);
613 assert_eq!(regtest.default_port, 18444);
614 assert!(regtest.is_testnet);
615 }
616
617 #[test]
618 fn test_network_parameters_consistency() {
619 let mainnet = NetworkParameters::mainnet().unwrap();
620 assert_eq!(mainnet.max_target, 0x1d00ffff);
621 assert_eq!(mainnet.halving_interval, 210000);
622
623 let testnet = NetworkParameters::testnet().unwrap();
624 assert_eq!(testnet.max_target, 0x1d00ffff);
625 assert_eq!(testnet.halving_interval, 210000);
626
627 let regtest = NetworkParameters::regtest().unwrap();
628 assert_eq!(regtest.max_target, 0x207fffff); assert_eq!(regtest.halving_interval, 150); }
631
632 #[test]
633 fn test_feature_support() {
634 let mainnet = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
635 assert!(mainnet.supports_feature("segwit"));
636 assert!(mainnet.supports_feature("taproot"));
637 assert!(mainnet.supports_feature("rbf"));
638 assert!(mainnet.supports_feature("ctv"));
639 assert!(!mainnet.supports_feature("fast_mining"));
640 assert!(!mainnet.supports_feature("nonexistent"));
641
642 let testnet = BitcoinProtocolEngine::new(ProtocolVersion::Testnet3).unwrap();
643 assert!(testnet.supports_feature("segwit"));
644 assert!(testnet.supports_feature("taproot"));
645 assert!(testnet.supports_feature("rbf"));
646 assert!(testnet.supports_feature("ctv"));
647 assert!(!testnet.supports_feature("fast_mining"));
648
649 let regtest = BitcoinProtocolEngine::new(ProtocolVersion::Regtest).unwrap();
650 assert!(regtest.supports_feature("segwit"));
651 assert!(regtest.supports_feature("taproot"));
652 assert!(regtest.supports_feature("rbf"));
653 assert!(regtest.supports_feature("ctv"));
654 assert!(regtest.supports_feature("fast_mining"));
655 }
656
657 #[test]
658 fn test_block_validation_empty_utxos() {
659 let engine = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
660 let utxos = UtxoSet::default();
661
662 let coinbase_tx = Transaction {
664 version: 1,
665 inputs: blvm_consensus::tx_inputs![TransactionInput {
666 prevout: OutPoint {
667 hash: [0u8; 32],
668 index: 0xffffffff,
669 },
670 script_sig: vec![0x01, 0x00], sequence: 0xffffffff,
672 }],
673 outputs: blvm_consensus::tx_outputs![TransactionOutput {
674 value: 50_0000_0000,
675 script_pubkey: vec![
676 blvm_consensus::opcodes::OP_DUP,
677 blvm_consensus::opcodes::OP_HASH160,
678 blvm_consensus::opcodes::PUSH_20_BYTES,
679 0x00,
680 0x00,
681 0x00,
682 0x00,
683 0x00,
684 0x00,
685 0x00,
686 0x00,
687 0x00,
688 0x00,
689 0x00,
690 0x00,
691 0x00,
692 0x00,
693 0x00,
694 0x00,
695 0x00,
696 0x00,
697 0x00,
698 0x00,
699 blvm_consensus::opcodes::OP_EQUALVERIFY,
700 blvm_consensus::opcodes::OP_CHECKSIG,
701 ], }],
703 lock_time: 0,
704 };
705
706 let merkle_root = blvm_consensus::mining::calculate_merkle_root(&[coinbase_tx.clone()])
708 .expect("Should calculate merkle root");
709
710 let block = Block {
711 header: BlockHeader {
712 version: 1,
713 prev_block_hash: [0u8; 32],
714 merkle_root,
715 timestamp: 1231006505,
716 bits: 0x1d00ffff,
717 nonce: 0,
718 },
719 transactions: vec![coinbase_tx].into_boxed_slice(),
720 };
721
722 let result = engine.validate_block(&block, &utxos, 0);
724 assert!(result.is_ok());
725 }
726
727 #[test]
728 fn test_transaction_validation() {
729 let engine = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
730
731 let tx = Transaction {
733 version: 1,
734 inputs: vec![TransactionInput {
735 prevout: OutPoint {
736 hash: [0u8; 32],
737 index: 0,
738 },
739 script_sig: vec![blvm_consensus::opcodes::PUSH_65_BYTES, 0x04],
740 sequence: 0xffffffff,
741 }]
742 .into(),
743 outputs: vec![TransactionOutput {
744 value: 50_0000_0000,
745 script_pubkey: vec![
746 blvm_consensus::opcodes::OP_DUP,
747 blvm_consensus::opcodes::OP_HASH160,
748 blvm_consensus::opcodes::PUSH_20_BYTES,
749 0x00,
750 0x00,
751 0x00,
752 0x00,
753 0x00,
754 0x00,
755 0x00,
756 0x00,
757 0x00,
758 0x00,
759 0x00,
760 0x00,
761 0x00,
762 0x00,
763 0x00,
764 0x00,
765 0x00,
766 0x00,
767 0x00,
768 0x00,
769 blvm_consensus::opcodes::OP_EQUALVERIFY,
770 blvm_consensus::opcodes::OP_CHECKSIG,
771 ], }]
773 .into(),
774 lock_time: 0,
775 };
776
777 let result = engine.validate_transaction(&tx);
778 assert!(result.is_ok());
779 }
780
781 #[test]
782 fn test_cross_protocol_validation() {
783 let mainnet_engine = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
784 let testnet_engine = BitcoinProtocolEngine::new(ProtocolVersion::Testnet3).unwrap();
785
786 assert_eq!(
788 mainnet_engine.supports_feature("segwit"),
789 testnet_engine.supports_feature("segwit")
790 );
791 assert_eq!(
792 mainnet_engine.supports_feature("taproot"),
793 testnet_engine.supports_feature("taproot")
794 );
795
796 assert_ne!(
798 mainnet_engine.get_network_params().magic_bytes,
799 testnet_engine.get_network_params().magic_bytes
800 );
801 assert_ne!(
802 mainnet_engine.get_network_params().default_port,
803 testnet_engine.get_network_params().default_port
804 );
805 }
806
807 #[test]
808 fn test_protocol_version_switching() {
809 let versions = vec![
811 ProtocolVersion::BitcoinV1,
812 ProtocolVersion::Testnet3,
813 ProtocolVersion::Regtest,
814 ];
815
816 for version in versions {
817 let engine = BitcoinProtocolEngine::new(version).unwrap();
818 assert_eq!(engine.get_protocol_version(), version);
819 }
820 }
821
822 #[test]
823 fn test_network_parameters_serialization() {
824 let mainnet = NetworkParameters::mainnet().unwrap();
825 let testnet = NetworkParameters::testnet().unwrap();
826 let regtest = NetworkParameters::regtest().unwrap();
827
828 let mainnet_json = serde_json::to_string(&mainnet).unwrap();
830 let mainnet_deserialized: NetworkParameters = serde_json::from_str(&mainnet_json).unwrap();
831 assert_eq!(mainnet.magic_bytes, mainnet_deserialized.magic_bytes);
832 assert_eq!(mainnet.default_port, mainnet_deserialized.default_port);
833 assert_eq!(mainnet.network_name, mainnet_deserialized.network_name);
834 assert_eq!(mainnet.is_testnet, mainnet_deserialized.is_testnet);
835
836 let testnet_json = serde_json::to_string(&testnet).unwrap();
837 let testnet_deserialized: NetworkParameters = serde_json::from_str(&testnet_json).unwrap();
838 assert_eq!(testnet.magic_bytes, testnet_deserialized.magic_bytes);
839
840 let regtest_json = serde_json::to_string(®test).unwrap();
841 let regtest_deserialized: NetworkParameters = serde_json::from_str(®test_json).unwrap();
842 assert_eq!(regtest.magic_bytes, regtest_deserialized.magic_bytes);
843 }
844
845 #[test]
846 fn test_protocol_version_serialization() {
847 let versions = vec![
848 ProtocolVersion::BitcoinV1,
849 ProtocolVersion::Testnet3,
850 ProtocolVersion::Regtest,
851 ];
852
853 for version in versions {
854 let json = serde_json::to_string(&version).unwrap();
855 let deserialized: ProtocolVersion = serde_json::from_str(&json).unwrap();
856 assert_eq!(version, deserialized);
857 }
858 }
859
860 #[test]
861 fn test_network_parameters_equality() {
862 let mainnet1 = NetworkParameters::mainnet().unwrap();
863 let mainnet2 = NetworkParameters::mainnet().unwrap();
864 let testnet = NetworkParameters::testnet().unwrap();
865
866 assert_eq!(mainnet1, mainnet2);
867 assert_ne!(mainnet1, testnet);
868 }
869
870 #[test]
871 fn test_protocol_version_equality() {
872 assert_eq!(ProtocolVersion::BitcoinV1, ProtocolVersion::BitcoinV1);
873 assert_ne!(ProtocolVersion::BitcoinV1, ProtocolVersion::Testnet3);
874 assert_ne!(ProtocolVersion::Testnet3, ProtocolVersion::Regtest);
875 }
876
877 #[test]
878 fn test_feature_activation_by_height() {
879 let engine = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
880
881 assert!(!engine.is_feature_active("segwit", 481_823, 1503539000));
883 assert!(engine.is_feature_active("segwit", 481_824, 1503539857));
884 assert!(engine.is_feature_active("segwit", 500_000, 1504000000));
885
886 assert!(!engine.is_feature_active("taproot", 709_631, 1636934000));
888 assert!(engine.is_feature_active("taproot", 709_632, 1636934400));
889 assert!(engine.is_feature_active("taproot", 800_000, 1640000000));
890 }
891
892 #[test]
893 fn test_economic_parameters_access() {
894 let engine = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
895 let params = engine.get_economic_parameters();
896
897 assert_eq!(params.initial_subsidy, 50_0000_0000);
898 assert_eq!(params.halving_interval, 210_000);
899 assert_eq!(params.coinbase_maturity, 100);
900
901 assert_eq!(params.get_block_subsidy(0), 50_0000_0000);
903 assert_eq!(params.get_block_subsidy(210_000), 25_0000_0000);
904 }
905
906 #[test]
907 fn test_feature_registry_access() {
908 let engine = BitcoinProtocolEngine::new(ProtocolVersion::BitcoinV1).unwrap();
909 let registry = engine.get_feature_registry();
910
911 assert!(registry.get_feature("segwit").is_some());
912 assert!(registry.get_feature("taproot").is_some());
913 assert!(registry.get_feature("nonexistent").is_none());
914
915 let features = registry.list_features();
916 assert!(features.contains(&"segwit".to_string()));
917 assert!(features.contains(&"taproot".to_string()));
918 }
919}