1use super::bitcoin::{TxIn, TxOut};
2use crate::contract_interface::ContractInterface;
3use crate::ordinals::OrdinalOperation;
4use crate::{events::*, Brc20Operation, StacksStackerDbChunk, DEFAULT_STACKS_NODE_RPC};
5use schemars::JsonSchema;
6use std::cmp::Ordering;
7use std::collections::HashSet;
8use std::fmt::Display;
9use std::hash::{Hash, Hasher};
10
11#[derive(Debug, Clone, Deserialize, Serialize, Default)]
13pub struct BlockIdentifier {
14 pub index: u64,
16 pub hash: String,
17}
18
19impl BlockIdentifier {
20 pub fn get_hash_bytes_str(&self) -> &str {
21 &self.hash[2..]
22 }
23
24 pub fn get_hash_bytes(&self) -> Vec<u8> {
25 hex::decode(&self.get_hash_bytes_str()).unwrap()
26 }
27}
28
29impl Display for BlockIdentifier {
30 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
31 write!(
32 f,
33 "Block #{} ({}...{})",
34 self.index,
35 &self.hash.as_str()[0..6],
36 &self.hash.as_str()[62..]
37 )
38 }
39}
40
41impl Hash for BlockIdentifier {
42 fn hash<H: Hasher>(&self, state: &mut H) {
43 self.hash.hash(state);
44 }
45}
46
47impl Ord for BlockIdentifier {
48 fn cmp(&self, other: &Self) -> Ordering {
49 (other.index, &other.hash).cmp(&(self.index, &self.hash))
50 }
51}
52
53impl PartialOrd for BlockIdentifier {
54 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
55 Some(other.cmp(self))
56 }
57}
58
59impl PartialEq for BlockIdentifier {
60 fn eq(&self, other: &Self) -> bool {
61 self.hash == other.hash
62 }
63}
64
65impl Eq for BlockIdentifier {}
66
67#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
74pub struct StacksBlockData {
75 pub block_identifier: BlockIdentifier,
76 pub parent_block_identifier: BlockIdentifier,
77 pub timestamp: i64,
81 pub transactions: Vec<StacksTransactionData>,
82 pub metadata: StacksBlockMetadata,
83}
84
85#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
88pub struct StacksMicroblockData {
89 pub block_identifier: BlockIdentifier,
90 pub parent_block_identifier: BlockIdentifier,
91 pub timestamp: i64,
95 pub transactions: Vec<StacksTransactionData>,
96 pub metadata: StacksMicroblockMetadata,
97}
98
99#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
100pub struct StacksMicroblockMetadata {
101 pub anchor_block_identifier: BlockIdentifier,
102}
103
104#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
105pub struct StacksMicroblocksTrail {
106 pub microblocks: Vec<StacksMicroblockData>,
107}
108
109#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
110pub struct StacksBlockMetadata {
111 pub bitcoin_anchor_block_identifier: BlockIdentifier,
112 pub pox_cycle_index: u32,
113 pub pox_cycle_position: u32,
114 pub pox_cycle_length: u32,
115 pub confirm_microblock_identifier: Option<BlockIdentifier>,
116 pub stacks_block_hash: String,
117
118 pub block_time: Option<u64>,
120 pub signer_bitvec: Option<String>,
121 pub signer_signature: Option<Vec<String>>,
122 pub signer_public_keys: Option<Vec<String>>,
123
124 pub cycle_number: Option<u64>,
126 pub reward_set: Option<StacksBlockMetadataRewardSet>,
127
128 pub tenure_height: Option<u64>,
130}
131
132#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
133pub struct StacksBlockMetadataRewardSet {
134 pub pox_ustx_threshold: String,
135 pub rewarded_addresses: Vec<String>,
136 pub signers: Option<Vec<StacksBlockMetadataRewardSetSigner>>,
137}
138
139#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
140pub struct StacksBlockMetadataRewardSetSigner {
141 pub signing_key: String,
142 pub weight: u32,
143 pub stacked_amt: String,
144}
145
146#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
153pub struct BitcoinBlockData {
154 pub block_identifier: BlockIdentifier,
155 pub parent_block_identifier: BlockIdentifier,
156 pub timestamp: u32,
160 pub transactions: Vec<BitcoinTransactionData>,
161 pub metadata: BitcoinBlockMetadata,
162}
163
164#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
165pub struct BitcoinBlockMetadata {
166 pub network: BitcoinNetwork,
167}
168
169#[derive(Debug, Clone, PartialEq, PartialOrd, Deserialize, Serialize)]
173pub struct Timestamp(i64);
174
175#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
178pub struct StacksTransactionData {
179 pub transaction_identifier: TransactionIdentifier,
180 pub operations: Vec<Operation>,
181 pub metadata: StacksTransactionMetadata,
184}
185
186#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
187#[serde(tag = "type", content = "data")]
188pub enum StacksTransactionKind {
189 ContractCall(StacksContractCallData),
190 ContractDeployment(StacksContractDeploymentData),
191 NativeTokenTransfer,
192 Coinbase,
193 TenureChange,
194 BitcoinOp(BitcoinOpData),
195 Unsupported,
196}
197
198#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
199#[serde(tag = "type", content = "data")]
200pub enum BitcoinOpData {
201 StackSTX(StackSTXData),
202 DelegateStackSTX(DelegateStackSTXData),
203}
204
205#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
206pub struct StackSTXData {
207 pub locked_amount: String,
208 pub unlock_height: String,
209 pub stacking_address: String,
210}
211
212#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
213pub struct DelegateStackSTXData {
214 pub stacking_address: String,
215 pub amount: String,
216 pub delegate: String,
217 pub pox_address: Option<String>,
218 pub unlock_height: Option<String>,
219}
220
221#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
222pub struct StacksContractCallData {
223 pub contract_identifier: String,
224 pub method: String,
225 pub args: Vec<String>,
226}
227
228#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
229pub struct StacksContractDeploymentData {
230 pub contract_identifier: String,
231 pub code: String,
232}
233
234#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
236pub struct StacksTransactionMetadata {
237 pub success: bool,
238 pub raw_tx: String,
239 pub result: String,
240 pub sender: String,
241 pub nonce: u64,
242 pub fee: u64,
243 pub kind: StacksTransactionKind,
244 pub receipt: StacksTransactionReceipt,
245 pub description: String,
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub sponsor: Option<String>,
248 #[serde(skip_serializing_if = "Option::is_none")]
249 pub execution_cost: Option<StacksTransactionExecutionCost>,
250 pub position: StacksTransactionPosition,
251 pub proof: Option<String>,
252 #[serde(skip_serializing_if = "Option::is_none")]
253 pub contract_abi: Option<ContractInterface>,
254}
255
256#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
258#[serde(untagged)]
259pub enum StacksTransactionPosition {
260 AnchorBlock(AnchorBlockPosition),
261 MicroBlock(MicroBlockPosition),
262}
263
264impl StacksTransactionPosition {
265 pub fn anchor_block(index: usize) -> StacksTransactionPosition {
266 StacksTransactionPosition::AnchorBlock(AnchorBlockPosition { index })
267 }
268
269 pub fn micro_block(
270 micro_block_identifier: BlockIdentifier,
271 index: usize,
272 ) -> StacksTransactionPosition {
273 StacksTransactionPosition::MicroBlock(MicroBlockPosition {
274 micro_block_identifier,
275 index,
276 })
277 }
278}
279
280#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
281pub struct AnchorBlockPosition {
282 index: usize,
283}
284
285#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
286pub struct MicroBlockPosition {
287 micro_block_identifier: BlockIdentifier,
288 index: usize,
289}
290
291#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
292pub struct StacksTransactionExecutionCost {
293 pub write_length: u64,
294 pub write_count: u64,
295 pub read_length: u64,
296 pub read_count: u64,
297 pub runtime: u64,
298}
299
300#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Default)]
302pub struct StacksTransactionReceipt {
303 pub mutated_contracts_radius: HashSet<String>,
304 pub mutated_assets_radius: HashSet<String>,
305 pub contract_calls_stack: HashSet<String>,
306 pub events: Vec<StacksTransactionEvent>,
307}
308
309impl StacksTransactionReceipt {
310 pub fn new(
311 mutated_contracts_radius: HashSet<String>,
312 mutated_assets_radius: HashSet<String>,
313 events: Vec<StacksTransactionEvent>,
314 ) -> StacksTransactionReceipt {
315 StacksTransactionReceipt {
316 mutated_contracts_radius,
317 mutated_assets_radius,
318 contract_calls_stack: HashSet::new(),
319 events,
320 }
321 }
322}
323
324#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
327pub struct BitcoinTransactionData {
328 pub transaction_identifier: TransactionIdentifier,
329 pub operations: Vec<Operation>,
330 pub metadata: BitcoinTransactionMetadata,
333}
334
335#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
337pub struct BitcoinTransactionMetadata {
338 pub inputs: Vec<TxIn>,
339 pub outputs: Vec<TxOut>,
340 pub stacks_operations: Vec<StacksBaseChainOperation>,
341 pub ordinal_operations: Vec<OrdinalOperation>,
342 pub brc20_operation: Option<Brc20Operation>,
343 pub proof: Option<String>,
344 pub fee: u64,
345 pub index: u32,
346}
347
348#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
349#[serde(rename_all = "snake_case")]
350pub enum StacksBaseChainOperation {
351 BlockCommitted(StacksBlockCommitmentData),
352 LeaderRegistered(KeyRegistrationData),
353 StxTransferred(TransferSTXData),
354 StxLocked(LockSTXData),
355}
356
357#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
358#[serde(rename_all = "snake_case")]
359pub struct StacksBlockCommitmentData {
360 pub block_hash: String,
361 pub pox_cycle_index: u64,
362 pub pox_cycle_length: u64,
363 pub pox_cycle_position: u64,
364 pub pox_sats_burnt: u64,
365 pub pox_sats_transferred: Vec<PoxReward>,
366 pub mining_address_post_commit: Option<String>,
368 pub mining_sats_left: u64,
369}
370
371#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
372#[serde(rename_all = "snake_case")]
373pub struct PoxReward {
374 pub recipient_address: String,
375 pub amount: u64,
376}
377
378#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
379pub struct KeyRegistrationData;
380
381#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
382pub struct PobBlockCommitmentData {
383 pub signers: Vec<String>,
384 pub stacks_block_hash: String,
385 pub amount: u64,
386}
387
388#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
389pub struct BlockCommitmentData {
390 pub stacks_block_hash: String,
391}
392
393#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
394pub struct TransferSTXData {
395 pub sender: String,
396 pub recipient: String,
397 pub amount: String,
398}
399
400#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
401pub struct LockSTXData {
402 pub sender: String,
403 pub amount: String,
404 pub duration: u64,
405}
406
407#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize, Hash, PartialOrd, Ord)]
410pub struct TransactionIdentifier {
411 pub hash: String,
414}
415
416impl TransactionIdentifier {
417 pub fn new(txid: &str) -> Self {
418 let lowercased_txid = txid.to_lowercase();
419 Self {
420 hash: match lowercased_txid.starts_with("0x") {
421 true => lowercased_txid,
422 false => format!("0x{}", lowercased_txid),
423 },
424 }
425 }
426
427 pub fn get_hash_bytes_str(&self) -> &str {
428 &self.hash[2..]
429 }
430
431 pub fn get_hash_bytes(&self) -> Vec<u8> {
432 hex::decode(&self.get_hash_bytes_str()).unwrap()
433 }
434
435 pub fn get_8_hash_bytes(&self) -> [u8; 8] {
436 let bytes = self.get_hash_bytes();
437 [
438 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
439 ]
440 }
441}
442
443#[derive(
444 Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, strum::EnumIter, strum::IntoStaticStr,
445)]
446#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
447pub enum OperationType {
448 Credit,
449 Debit,
450 Lock,
451}
452
453#[derive(Debug, Clone, Default, PartialEq, Deserialize, Serialize)]
454pub struct OperationMetadata {
455 #[serde(skip_serializing_if = "Option::is_none")]
457 pub public_key: Option<PublicKey>,
458 #[serde(skip_serializing_if = "Option::is_none")]
463 pub code: Option<String>,
464 #[serde(skip_serializing_if = "Option::is_none")]
466 pub method_name: Option<String>,
467 #[serde(skip_serializing_if = "Option::is_none")]
469 pub args: Option<String>,
470}
471
472#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
476pub struct PublicKey {
477 pub hex_bytes: Option<String>,
479 pub curve_type: CurveType,
480}
481
482#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
484#[serde(rename_all = "lowercase")]
485pub enum CurveType {
486 Edwards25519,
488 Secp256k1,
490}
491
492#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
496pub struct Operation {
497 pub operation_identifier: OperationIdentifier,
498
499 #[serde(skip_serializing_if = "Option::is_none")]
505 pub related_operations: Option<Vec<OperationIdentifier>>,
506
507 #[serde(rename = "type")]
511 pub type_: OperationType,
512
513 #[serde(skip_serializing_if = "Option::is_none")]
519 pub status: Option<OperationStatusKind>,
520
521 pub account: AccountIdentifier,
522
523 #[serde(skip_serializing_if = "Option::is_none")]
524 pub amount: Option<Amount>,
525
526 #[serde(skip_serializing_if = "Option::is_none")]
527 pub metadata: Option<OperationMetadata>,
528}
529
530#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
533pub struct OperationIdentifier {
534 pub index: u32,
540
541 #[serde(skip_serializing_if = "Option::is_none")]
547 pub network_index: Option<i64>,
548}
549
550#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize, strum::EnumIter)]
551#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
552pub enum OperationStatusKind {
553 Success,
554}
555
556#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
560pub struct AccountIdentifier {
561 pub address: String,
564
565 #[serde(skip_serializing_if = "Option::is_none")]
566 pub sub_account: Option<SubAccountIdentifier>,
567 }
575
576#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
580pub struct SubAccountIdentifier {
581 pub address: SubAccount,
584 }
593
594#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Hash)]
595#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
596pub enum SubAccount {
597 LiquidBalanceForStorage,
598 Locked,
599}
600
601#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
604pub struct Amount {
605 pub value: u128,
609
610 pub currency: Currency,
611 }
616
617#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
621pub struct Currency {
622 pub symbol: String,
624
625 pub decimals: u32,
630
631 #[serde(skip_serializing_if = "Option::is_none")]
633 pub metadata: Option<CurrencyMetadata>,
634}
635
636#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
637#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
638pub enum CurrencyStandard {
639 Sip09,
640 Sip10,
641 None,
642}
643
644#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
645pub struct CurrencyMetadata {
646 pub asset_class_identifier: String,
647 pub asset_identifier: Option<String>,
648 pub standard: CurrencyStandard,
649}
650
651#[allow(dead_code)]
652#[derive(Debug, Clone, PartialEq, Serialize)]
653pub enum BlockchainEvent {
654 BlockchainUpdatedWithHeaders(BlockchainUpdatedWithHeaders),
655 BlockchainUpdatedWithReorg(BlockchainUpdatedWithReorg),
656}
657
658#[derive(Debug, Clone, PartialEq, Serialize)]
659pub struct BlockchainUpdatedWithHeaders {
660 pub new_headers: Vec<BlockHeader>,
661 pub confirmed_headers: Vec<BlockHeader>,
662}
663
664#[derive(Debug, Clone, PartialEq, Serialize)]
665pub struct BlockchainUpdatedWithReorg {
666 pub headers_to_rollback: Vec<BlockHeader>,
667 pub headers_to_apply: Vec<BlockHeader>,
668 pub confirmed_headers: Vec<BlockHeader>,
669}
670
671#[derive(Clone, Debug, PartialEq, Serialize)]
672#[serde(tag = "type", content = "data")]
673pub enum StacksNonConsensusEventPayloadData {
674 SignerMessage(StacksStackerDbChunk),
675}
676
677#[derive(Clone, Debug, PartialEq, Serialize)]
678pub struct StacksNonConsensusEventData {
679 pub payload: StacksNonConsensusEventPayloadData,
680 pub received_at_ms: u64,
681 pub received_at_block: BlockIdentifier,
682}
683
684#[derive(Debug, Clone, PartialEq, Serialize)]
685pub struct BlockHeader {
686 pub block_identifier: BlockIdentifier,
687 pub parent_block_identifier: BlockIdentifier,
688}
689
690#[allow(dead_code)]
691#[derive(Debug, Clone, PartialEq, Serialize)]
692pub enum BitcoinChainEvent {
693 ChainUpdatedWithBlocks(BitcoinChainUpdatedWithBlocksData),
694 ChainUpdatedWithReorg(BitcoinChainUpdatedWithReorgData),
695}
696
697#[derive(Debug, Clone, PartialEq, Serialize)]
698pub struct BitcoinChainUpdatedWithBlocksData {
699 pub new_blocks: Vec<BitcoinBlockData>,
700 pub confirmed_blocks: Vec<BitcoinBlockData>,
701}
702
703#[derive(Debug, Clone, PartialEq, Serialize)]
704pub struct BitcoinChainUpdatedWithReorgData {
705 pub blocks_to_rollback: Vec<BitcoinBlockData>,
706 pub blocks_to_apply: Vec<BitcoinBlockData>,
707 pub confirmed_blocks: Vec<BitcoinBlockData>,
708}
709
710#[derive(Debug, Clone, PartialEq, Serialize)]
711pub struct StacksChainUpdatedWithNonConsensusEventsData {
712 pub events: Vec<StacksNonConsensusEventData>,
713}
714
715#[allow(dead_code)]
716#[derive(Debug, Clone, PartialEq, Serialize)]
717pub enum StacksChainEvent {
718 ChainUpdatedWithBlocks(StacksChainUpdatedWithBlocksData),
719 ChainUpdatedWithReorg(StacksChainUpdatedWithReorgData),
720 ChainUpdatedWithMicroblocks(StacksChainUpdatedWithMicroblocksData),
721 ChainUpdatedWithMicroblocksReorg(StacksChainUpdatedWithMicroblocksReorgData),
722 ChainUpdatedWithNonConsensusEvents(StacksChainUpdatedWithNonConsensusEventsData),
723}
724
725impl StacksChainEvent {
726 pub fn get_confirmed_blocks(self) -> Vec<StacksBlockData> {
727 match self {
728 StacksChainEvent::ChainUpdatedWithBlocks(event) => event.confirmed_blocks,
729 StacksChainEvent::ChainUpdatedWithReorg(event) => event.confirmed_blocks,
730 _ => vec![],
731 }
732 }
733
734 pub fn get_latest_block_identifier(&self) -> Option<&BlockIdentifier> {
735 match self {
736 StacksChainEvent::ChainUpdatedWithBlocks(event) => event
737 .new_blocks
738 .last()
739 .and_then(|b| Some(&b.block.block_identifier)),
740 StacksChainEvent::ChainUpdatedWithReorg(event) => event
741 .blocks_to_apply
742 .last()
743 .and_then(|b| Some(&b.block.block_identifier)),
744 StacksChainEvent::ChainUpdatedWithMicroblocks(event) => event
745 .new_microblocks
746 .first()
747 .and_then(|b| Some(&b.metadata.anchor_block_identifier)),
748 StacksChainEvent::ChainUpdatedWithMicroblocksReorg(event) => event
749 .microblocks_to_apply
750 .first()
751 .and_then(|b| Some(&b.metadata.anchor_block_identifier)),
752 StacksChainEvent::ChainUpdatedWithNonConsensusEvents(_) => None,
753 }
754 }
755}
756
757#[derive(Debug, Clone, PartialEq, Serialize)]
758pub struct StacksBlockUpdate {
759 pub block: StacksBlockData,
760 pub parent_microblocks_to_rollback: Vec<StacksMicroblockData>,
761 pub parent_microblocks_to_apply: Vec<StacksMicroblockData>,
762}
763
764impl StacksBlockUpdate {
765 pub fn new(block: StacksBlockData) -> StacksBlockUpdate {
766 StacksBlockUpdate {
767 block,
768 parent_microblocks_to_rollback: vec![],
769 parent_microblocks_to_apply: vec![],
770 }
771 }
772}
773
774#[derive(Debug, Clone, PartialEq, Serialize)]
775pub struct StacksChainUpdatedWithBlocksData {
776 pub new_blocks: Vec<StacksBlockUpdate>,
777 pub confirmed_blocks: Vec<StacksBlockData>,
778}
779
780#[derive(Debug, Clone, PartialEq, Serialize)]
781pub struct StacksChainUpdatedWithReorgData {
782 pub blocks_to_rollback: Vec<StacksBlockUpdate>,
783 pub blocks_to_apply: Vec<StacksBlockUpdate>,
784 pub confirmed_blocks: Vec<StacksBlockData>,
785}
786
787#[derive(Debug, Clone, PartialEq, Serialize)]
788pub struct StacksChainUpdatedWithMicroblocksData {
789 pub new_microblocks: Vec<StacksMicroblockData>,
790}
791
792#[derive(Debug, Clone, PartialEq, Serialize)]
793pub struct StacksChainUpdatedWithMicroblocksReorgData {
794 pub microblocks_to_rollback: Vec<StacksMicroblockData>,
795 pub microblocks_to_apply: Vec<StacksMicroblockData>,
796}
797
798#[derive(
799 Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Serialize, Deserialize, JsonSchema,
800)]
801#[serde(rename_all = "snake_case")]
802pub enum StacksNetwork {
803 Simnet,
804 Devnet,
805 Testnet,
806 Mainnet,
807}
808
809impl std::fmt::Display for StacksNetwork {
810 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
811 write!(f, "{}", self.as_str())
812 }
813}
814impl StacksNetwork {
815 pub fn from_str(network: &str) -> Result<StacksNetwork, String> {
816 let value = match network {
817 "devnet" => StacksNetwork::Devnet,
818 "testnet" => StacksNetwork::Testnet,
819 "mainnet" => StacksNetwork::Mainnet,
820 "simnet" => StacksNetwork::Simnet,
821 _ => {
822 return Err(format!(
823 "network '{}' unsupported (mainnet, testnet, devnet, simnet)",
824 network
825 ))
826 }
827 };
828 Ok(value)
829 }
830
831 pub fn as_str(&self) -> &str {
832 match self {
833 StacksNetwork::Devnet => "devnet",
834 StacksNetwork::Testnet => "testnet",
835 StacksNetwork::Mainnet => "mainnet",
836 StacksNetwork::Simnet => "simnet",
837 }
838 }
839
840 pub fn is_simnet(&self) -> bool {
841 match self {
842 StacksNetwork::Simnet => true,
843 _ => false,
844 }
845 }
846
847 pub fn is_testnet(&self) -> bool {
848 match self {
849 StacksNetwork::Testnet => true,
850 _ => false,
851 }
852 }
853
854 pub fn either_devnet_or_testnet(&self) -> bool {
855 match self {
856 StacksNetwork::Devnet | StacksNetwork::Testnet => true,
857 _ => false,
858 }
859 }
860
861 pub fn either_testnet_or_mainnet(&self) -> bool {
862 match self {
863 StacksNetwork::Mainnet | StacksNetwork::Testnet => true,
864 _ => false,
865 }
866 }
867
868 pub fn is_devnet(&self) -> bool {
869 match self {
870 StacksNetwork::Devnet => true,
871 _ => false,
872 }
873 }
874
875 pub fn is_mainnet(&self) -> bool {
876 match self {
877 StacksNetwork::Mainnet => true,
878 _ => false,
879 }
880 }
881
882 pub fn get_networks(&self) -> (BitcoinNetwork, StacksNetwork) {
883 match &self {
884 StacksNetwork::Simnet => (BitcoinNetwork::Regtest, StacksNetwork::Simnet),
885 StacksNetwork::Devnet => (BitcoinNetwork::Testnet, StacksNetwork::Devnet),
886 StacksNetwork::Testnet => (BitcoinNetwork::Testnet, StacksNetwork::Testnet),
887 StacksNetwork::Mainnet => (BitcoinNetwork::Mainnet, StacksNetwork::Mainnet),
888 }
889 }
890}
891
892#[allow(dead_code)]
893#[derive(
894 Debug, PartialEq, Eq, Clone, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
895)]
896#[serde(rename_all = "snake_case")]
897pub enum BitcoinNetwork {
898 Regtest,
899 Testnet,
900 Signet,
901 Mainnet,
902}
903
904impl std::fmt::Display for BitcoinNetwork {
905 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
906 write!(f, "{}", self.as_str())
907 }
908}
909impl BitcoinNetwork {
910 pub fn from_str(network: &str) -> Result<BitcoinNetwork, String> {
911 let value = match network {
912 "regtest" => BitcoinNetwork::Regtest,
913 "testnet" => BitcoinNetwork::Testnet,
914 "mainnet" => BitcoinNetwork::Mainnet,
915 "signet" => BitcoinNetwork::Signet,
916 _ => {
917 return Err(format!(
918 "network '{}' unsupported (mainnet, testnet, regtest, signet)",
919 network
920 ))
921 }
922 };
923 Ok(value)
924 }
925
926 pub fn as_str(&self) -> &str {
927 match self {
928 BitcoinNetwork::Regtest => "regtest",
929 BitcoinNetwork::Testnet => "testnet",
930 BitcoinNetwork::Mainnet => "mainnet",
931 BitcoinNetwork::Signet => "signet",
932 }
933 }
934}
935
936#[derive(Deserialize, Debug, Clone, PartialEq)]
937pub enum BitcoinBlockSignaling {
938 Stacks(StacksNodeConfig),
939 ZeroMQ(String),
940}
941
942#[derive(Deserialize, Debug, Clone, PartialEq)]
943pub struct StacksNodeConfig {
944 pub rpc_url: String,
945 pub ingestion_port: u16,
946}
947
948impl StacksNodeConfig {
949 pub fn new(rpc_url: String, ingestion_port: u16) -> StacksNodeConfig {
950 StacksNodeConfig {
951 rpc_url,
952 ingestion_port,
953 }
954 }
955
956 pub fn default_localhost(ingestion_port: u16) -> StacksNodeConfig {
957 StacksNodeConfig {
958 rpc_url: DEFAULT_STACKS_NODE_RPC.to_string(),
959 ingestion_port,
960 }
961 }
962}
963
964impl BitcoinBlockSignaling {
965 pub fn should_ignore_bitcoin_block_signaling_through_stacks(&self) -> bool {
966 match &self {
967 BitcoinBlockSignaling::Stacks(_) => false,
968 _ => true,
969 }
970 }
971
972 pub fn is_bitcoind_zmq_block_signaling_expected(&self) -> bool {
973 match &self {
974 BitcoinBlockSignaling::ZeroMQ(_) => false,
975 _ => true,
976 }
977 }
978}