use bitcoin::BlockHash;
use bitcoin::hashes::Hash;
use serde::{Deserialize, Serialize};
use urma_chain::observation::Chain;
pub const API_VERSION: u32 = 1;
pub const SCAN_RULES_VERSION: u32 = 1;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PinReceipt {
pub root: bitcoin::Txid,
pub pinned: bool,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct PruneReceipt {
pub records_removed: u64,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct RecordPackage {
pub version: u32,
pub chain_genesis: BlockHash,
pub block: ChainPoint,
pub reveal: urma_chain::inclusion::TransactionProof,
pub commit: Vec<u8>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RecordReceipt {
pub generation: u64,
pub block: ChainPoint,
pub position: u32,
pub txid: bitcoin::Txid,
pub wtxid: bitcoin::Wtxid,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ArchivedRecord {
pub receipt: RecordReceipt,
pub package: RecordPackage,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ObjectStatus {
pub root: bitcoin::Txid,
pub verified_generation: u64,
pub payload_bytes: u64,
pub members_total: u64,
pub members_local: u64,
pub members_selected: u64,
pub pinned: bool,
}
impl ObjectStatus {
pub fn locally_complete(&self) -> bool {
self.members_total > 0 && self.members_local == self.members_total
}
pub fn selected_complete(&self) -> bool {
self.locally_complete() && self.members_selected == self.members_total
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize)]
pub struct ChainPoint {
pub height: u64,
pub hash: BlockHash,
}
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum Retention {
Pruned,
#[default]
Unpruned,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ArchiveConfig {
pub chain: Chain,
pub application_start: ChainPoint,
pub retention: Retention,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ArchiveStatus {
pub api_version: u32,
pub chain_genesis: BlockHash,
pub application_start: ChainPoint,
pub retention: Retention,
pub generation: u64,
pub selected_tip: Option<ChainPoint>,
pub indexed_through: Option<ChainPoint>,
pub scanned_blocks: u64,
pub unresolved_dependencies: u64,
pub stored_transactions: u64,
pub scan_rules_version: u32,
pub peer_synced_through: Option<ChainPoint>,
pub peer_omissions: u64,
pub unaudited_records: u64,
}
impl Default for ArchiveStatus {
fn default() -> Self {
let zero = BlockHash::all_zeros();
Self {
api_version: API_VERSION,
chain_genesis: zero,
application_start: ChainPoint {
height: 0,
hash: zero,
},
retention: Retention::default(),
generation: 0,
selected_tip: None,
indexed_through: None,
scanned_blocks: 0,
unresolved_dependencies: 0,
stored_transactions: 0,
scan_rules_version: SCAN_RULES_VERSION,
peer_synced_through: None,
peer_omissions: 0,
unaudited_records: 0,
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CacheReceipt {
pub enabled: bool,
pub limit_bytes: u64,
pub before_bytes: u64,
pub remaining_bytes: u64,
pub removed_records: u64,
pub removed_transactions: u64,
pub over_budget: bool,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[non_exhaustive]
pub struct ServiceStatus {
pub archive: ArchiveStatus,
pub last_sync_error: Option<String>,
pub last_sync_error_at: Option<u64>,
pub last_retention_error: Option<String>,
pub last_retention_error_at: Option<u64>,
pub last_names_error: Option<String>,
pub last_names_error_at: Option<u64>,
pub last_dependency_error: Option<String>,
pub last_dependency_error_at: Option<u64>,
pub last_inventory_error: Option<String>,
pub last_inventory_error_at: Option<u64>,
pub last_discovery_error: Option<String>,
pub last_discovery_error_at: Option<u64>,
pub commit_sources: Vec<CommitSourceStatus>,
pub cache_limit_bytes: u64,
pub last_cache_error: Option<String>,
pub last_cache_error_at: Option<u64>,
pub last_cache_maintenance: Option<CacheReceipt>,
pub overlay: Option<OverlayStatus>,
#[serde(default)]
pub chain_peers: u64,
#[serde(default)]
pub chain_target: Option<u64>,
pub retention_configured: bool,
pub record_sources_configured: u64,
pub capabilities: Vec<String>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct CommitSourceStatus {
pub label: String,
pub last_error: Option<String>,
pub last_error_at: Option<u64>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct OverlayStatus {
pub peer_id: String,
#[serde(default)]
pub listen: Vec<String>,
#[serde(default)]
pub announce: Vec<String>,
pub peer_book: u64,
pub connected: u64,
pub admitted: u64,
pub rejected: u64,
pub peers: Vec<OverlayPeerStatus>,
pub discovery: Option<DiscoveryStatus>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct DiscoveryStatus {
pub seeds: u64,
pub book: u64,
pub reached: u64,
pub reached_ever: u64,
pub gossip: u64,
pub last_seed_round_error: Option<String>,
pub last_seed_round_error_at: Option<u64>,
pub last_gossip_error: Option<String>,
pub last_gossip_error_at: Option<u64>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Omission {
pub peer: String,
pub block: ChainPoint,
pub position: u32,
pub txid: bitcoin::Txid,
pub generation: u64,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum BookOrigin {
Gossip,
Seed,
Manual,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct BookEntry {
pub peer_id: Option<String>,
pub addrs: Vec<String>,
pub origin: BookOrigin,
pub last_success: Option<u64>,
pub failures: u32,
pub banned_until: Option<u64>,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
#[non_exhaustive]
pub struct OverlayPeerStatus {
pub label: String,
pub cursor: u64,
pub synced_through: Option<u64>,
pub last_error: Option<String>,
pub last_error_at: Option<u64>,
pub backoff_until: Option<u64>,
pub last_progress_at: Option<u64>,
}
#[cfg(test)]
#[path = "model_tests.rs"]
mod model_tests;