aptos_network_sdk/
block.rs

1use serde::{Deserialize, Serialize};
2use std::sync::Arc;
3
4use crate::{Aptos, trade::TransactionInfo};
5
6#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct Block {
8    pub block_height: String,
9    pub block_hash: String,
10    #[serde(rename = "block_timestamp")]
11    pub timestamp: String,
12    pub first_version: String,
13    pub last_version: String,
14    #[serde(default)]
15    pub transactions: Option<Vec<TransactionInfo>>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct BlockInfo {
20    /// Block height
21    pub block_height: u64,
22    /// Block hash
23    pub block_hash: String,
24    /// First version in block
25    pub first_version: u64,
26    /// Last version in block
27    pub last_version: u64,
28    /// Block timestamp in microseconds since epoch
29    pub timestamp: u64,
30    /// Transaction count in block
31    pub transaction_count: usize,
32    /// Block transactions
33    pub transactions: Option<Vec<TransactionInfo>>,
34}
35
36impl BlockInfo {
37    /// Convert from Aptos Block
38    pub fn from_aptos_block(block: &Block) -> Self {
39        let transaction_count = block.transactions.as_ref().map_or(0, |v| v.len());
40
41        Self {
42            block_height: block.block_height.parse::<u64>().unwrap_or(0),
43            block_hash: block.block_hash.clone(),
44            first_version: block.first_version.parse::<u64>().unwrap_or(0),
45            last_version: block.last_version.parse::<u64>().unwrap_or(0),
46            timestamp: block.timestamp.parse::<u64>().unwrap_or(0),
47            transaction_count,
48            transactions: None,
49        }
50    }
51
52    /// Convert from Aptos Block with full transactions
53    pub fn from_aptos_block_with_txs(block: &Block, transactions: Vec<TransactionInfo>) -> Self {
54        let transaction_count = transactions.len();
55
56        Self {
57            block_height: block.block_height.parse::<u64>().unwrap_or(0),
58            block_hash: block.block_hash.clone(),
59            first_version: block.first_version.parse::<u64>().unwrap_or(0),
60            last_version: block.last_version.parse::<u64>().unwrap_or(0),
61            timestamp: block.timestamp.parse::<u64>().unwrap_or(0),
62            transaction_count,
63            transactions: Some(transactions),
64        }
65    }
66
67    /// Get block timestamp in seconds
68    pub fn timestamp_seconds(&self) -> f64 {
69        self.timestamp as f64 / 1_000_000.0
70    }
71
72    /// Get block timestamp in milliseconds
73    pub fn timestamp_millis(&self) -> u64 {
74        self.timestamp / 1000
75    }
76
77    /// Get transactions per second (TPS) for this block
78    pub fn tps(&self) -> Option<f64> {
79        if self.timestamp > 0 {
80            let duration_seconds = self.timestamp_seconds();
81            if duration_seconds > 0.0 {
82                return Some(self.transaction_count as f64 / duration_seconds);
83            }
84        }
85        None
86    }
87
88    /// Get block time in seconds
89    pub fn block_time_seconds(&self) -> Option<f64> {
90        if self.timestamp > 0 {
91            Some(self.timestamp_seconds())
92        } else {
93            None
94        }
95    }
96
97    /// Check if block contains transactions
98    pub fn has_transactions(&self) -> bool {
99        self.transaction_count > 0
100    }
101
102    /// Get transaction version range
103    pub fn transaction_version_range(&self) -> (u64, u64) {
104        (self.first_version, self.last_version)
105    }
106
107    /// Calculate block size (approximation)
108    pub fn estimated_size(&self) -> usize {
109        // Basic estimation: 100 bytes per transaction + base block size
110        let base_size = 500; // Base block metadata size
111        base_size + (self.transaction_count * 100)
112    }
113}
114#[cfg(test)]
115mod tests {
116    use crate::AptosType;
117
118    use super::*;
119    use std::sync::Arc;
120
121    #[tokio::test]
122    async fn test_get_latest_block() {
123        let aptos = Arc::new(Aptos::new(AptosType::Testnet));
124        let chain_height_result = aptos.get_chain_height().await;
125        match chain_height_result {
126            Ok(height) => {
127                println!("Chain height: {}", height);
128                match aptos.get_block_by_height(height).await {
129                    Ok(block) => {
130                        let block_info = BlockInfo::from_aptos_block(&block);
131                        println!("✅ Successfully got latest block");
132                        println!("   Block height: {}", block_info.block_height);
133                        println!("   Block hash: {}", block_info.block_hash);
134                        println!("   Timestamp: {}", block_info.timestamp);
135                        println!("   Transaction count: {}", block_info.transaction_count);
136                        // Test conversion functions
137                        println!("   Timestamp (seconds): {}", block_info.timestamp_seconds());
138                        println!("   Timestamp (millis): {}", block_info.timestamp_millis());
139                        if let Some(tps) = block_info.tps() {
140                            println!("   Estimated TPS: {:.2}", tps);
141                        }
142                        if let Some(block_time) = block_info.block_time_seconds() {
143                            println!("   Block time: {:.2} seconds", block_time);
144                        }
145                        println!("   Estimated size: {} bytes", block_info.estimated_size());
146                        println!(
147                            "   Transaction range: {:?}",
148                            block_info.transaction_version_range()
149                        );
150                        println!("   Has transactions: {}", block_info.has_transactions());
151                    }
152                    Err(e) => {
153                        println!("❌ Failed to get block by height: {}", e);
154                    }
155                }
156            }
157            Err(e) => {
158                println!("❌ Failed to get chain height: {}", e);
159            }
160        }
161    }
162}