rustywallet_vanity/
result.rs1use crate::pattern::Pattern;
4use rustywallet_keys::prelude::*;
5use std::time::Duration;
6
7#[derive(Debug, Clone)]
9pub struct VanityResult {
10 pub private_key: PrivateKey,
12 pub public_key: PublicKey,
14 pub address: String,
16 pub matched_pattern: Pattern,
18 pub stats: SearchStats,
20}
21
22impl VanityResult {
23 pub fn new(
25 private_key: PrivateKey,
26 address: String,
27 matched_pattern: Pattern,
28 stats: SearchStats,
29 ) -> Self {
30 let public_key = private_key.public_key();
31 Self {
32 private_key,
33 public_key,
34 address,
35 matched_pattern,
36 stats,
37 }
38 }
39}
40
41#[derive(Debug, Clone)]
43pub struct SearchStats {
44 pub attempts: u64,
46 pub elapsed: Duration,
48 pub rate: f64,
50}
51
52impl SearchStats {
53 pub fn new(attempts: u64, elapsed: Duration) -> Self {
55 let rate = if elapsed.as_secs_f64() > 0.0 {
56 attempts as f64 / elapsed.as_secs_f64()
57 } else {
58 0.0
59 };
60
61 Self {
62 attempts,
63 elapsed,
64 rate,
65 }
66 }
67}
68
69#[derive(Debug, Clone)]
71pub struct SearchProgress {
72 pub attempts: u64,
74 pub elapsed: Duration,
76 pub rate: f64,
78 pub estimated_remaining: Option<Duration>,
80}
81
82impl SearchProgress {
83 pub fn new(attempts: u64, elapsed: Duration, expected_attempts: Option<u64>) -> Self {
85 let rate = if elapsed.as_secs_f64() > 0.0 {
86 attempts as f64 / elapsed.as_secs_f64()
87 } else {
88 0.0
89 };
90
91 let estimated_remaining = expected_attempts.and_then(|expected| {
92 if rate > 0.0 && attempts < expected {
93 let remaining_attempts = expected - attempts;
94 Some(Duration::from_secs_f64(remaining_attempts as f64 / rate))
95 } else {
96 None
97 }
98 });
99
100 Self {
101 attempts,
102 elapsed,
103 rate,
104 estimated_remaining,
105 }
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn test_search_stats() {
115 let stats = SearchStats::new(1000, Duration::from_secs(1));
116 assert_eq!(stats.attempts, 1000);
117 assert!((stats.rate - 1000.0).abs() < 0.1);
118 }
119
120 #[test]
121 fn test_search_progress() {
122 let progress = SearchProgress::new(500, Duration::from_secs(1), Some(1000));
123 assert_eq!(progress.attempts, 500);
124 assert!(progress.estimated_remaining.is_some());
125 }
126}