cuprate_rpc_types/
from.rs

1//! [`From`] implementations from other crate's types into [`crate`] types.
2//!
3//! Only non-crate types are imported, all crate types use `crate::`.
4
5use std::{
6    net::{SocketAddr, SocketAddrV4},
7    time::Duration,
8};
9
10use cuprate_helper::{fmt::HexPrefix, map::ipv4_from_u32};
11use cuprate_hex::{Hex, HexVec};
12use cuprate_p2p_core::{
13    types::{ConnectionId, ConnectionInfo, SetBan, Span},
14    NetZoneAddress,
15};
16use cuprate_types::rpc::{BlockHeader, ChainInfo, HistogramEntry, SpentKeyImageInfo, TxInfo};
17
18impl From<BlockHeader> for crate::misc::BlockHeader {
19    fn from(x: BlockHeader) -> Self {
20        Self {
21            block_size: x.block_weight,
22            block_weight: x.block_weight,
23            cumulative_difficulty_top64: x.cumulative_difficulty_top64,
24            cumulative_difficulty: x.cumulative_difficulty,
25            depth: x.depth,
26            difficulty_top64: x.difficulty_top64,
27            difficulty: x.difficulty,
28            hash: Hex(x.hash),
29            height: x.height,
30            long_term_weight: x.long_term_weight,
31            major_version: x.major_version,
32            miner_tx_hash: Hex(x.miner_tx_hash),
33            minor_version: x.minor_version,
34            nonce: x.nonce,
35            num_txes: x.num_txes,
36            orphan_status: x.orphan_status,
37            pow_hash: x.pow_hash.map_or_else(HexVec::new, |a| HexVec(a.into())),
38            prev_hash: Hex(x.prev_hash),
39            reward: x.reward,
40            timestamp: x.timestamp,
41            // FIXME: if we made a type that automatically did `hex_prefix_u128`,
42            //  we wouldn't need `crate::misc::BlockHeader`.
43            wide_cumulative_difficulty: (x.cumulative_difficulty, x.cumulative_difficulty_top64)
44                .hex_prefix(),
45            wide_difficulty: (x.difficulty, x.difficulty_top64).hex_prefix(),
46        }
47    }
48}
49
50impl<A: NetZoneAddress> From<ConnectionInfo<A>> for crate::misc::ConnectionInfo {
51    fn from(x: ConnectionInfo<A>) -> Self {
52        let (ip, port) = match x.socket_addr {
53            Some(socket) => (socket.ip().to_string(), socket.port().to_string()),
54            None => (String::new(), String::new()),
55        };
56
57        Self {
58            address: x.address.to_string(),
59            address_type: x.address_type,
60            avg_download: x.avg_download,
61            avg_upload: x.avg_upload,
62            connection_id: String::from(ConnectionId::DEFAULT_STR),
63            current_download: x.current_download,
64            current_upload: x.current_upload,
65            height: x.height,
66            host: x.host,
67            incoming: x.incoming,
68            ip,
69            live_time: x.live_time,
70            localhost: x.localhost,
71            local_ip: x.local_ip,
72            peer_id: hex::encode(x.peer_id.to_ne_bytes()),
73            port,
74            pruning_seed: x.pruning_seed.compress(),
75            recv_count: x.recv_count,
76            recv_idle_time: x.recv_idle_time,
77            rpc_credits_per_hash: x.rpc_credits_per_hash,
78            rpc_port: x.rpc_port,
79            send_count: x.send_count,
80            send_idle_time: x.send_idle_time,
81            state: x.state,
82            support_flags: x.support_flags,
83        }
84    }
85}
86
87// TODO: support non-clearnet addresses.
88impl From<crate::misc::SetBan> for SetBan<SocketAddr> {
89    fn from(x: crate::misc::SetBan) -> Self {
90        let address = SocketAddr::V4(SocketAddrV4::new(ipv4_from_u32(x.ip), 0));
91
92        let ban = if x.ban {
93            Some(Duration::from_secs(x.seconds.into()))
94        } else {
95            None
96        };
97
98        Self { address, ban }
99    }
100}
101
102// TODO: do we need this type?
103impl From<HistogramEntry> for crate::misc::HistogramEntry {
104    fn from(x: HistogramEntry) -> Self {
105        Self {
106            amount: x.amount,
107            total_instances: x.total_instances,
108            unlocked_instances: x.unlocked_instances,
109            recent_instances: x.recent_instances,
110        }
111    }
112}
113
114impl From<ChainInfo> for crate::misc::ChainInfo {
115    fn from(x: ChainInfo) -> Self {
116        Self {
117            block_hash: Hex(x.block_hash),
118            block_hashes: x.block_hashes.into_iter().map(Hex).collect(),
119            difficulty_top64: x.difficulty_top64,
120            difficulty: x.difficulty,
121            height: x.height,
122            length: x.length,
123            main_chain_parent_block: Hex(x.main_chain_parent_block),
124            wide_difficulty: (x.difficulty, x.difficulty_top64).hex_prefix(),
125        }
126    }
127}
128
129// TODO: support non-clearnet addresses.
130impl From<Span<SocketAddr>> for crate::misc::Span {
131    fn from(x: Span<SocketAddr>) -> Self {
132        Self {
133            connection_id: String::from(ConnectionId::DEFAULT_STR),
134            nblocks: x.nblocks,
135            rate: x.rate,
136            remote_address: x.remote_address.to_string(),
137            size: x.size,
138            speed: x.speed,
139            start_block_height: x.start_block_height,
140        }
141    }
142}
143
144impl From<TxInfo> for crate::misc::TxInfo {
145    fn from(x: TxInfo) -> Self {
146        Self {
147            blob_size: x.blob_size,
148            do_not_relay: x.do_not_relay,
149            double_spend_seen: x.double_spend_seen,
150            fee: x.fee,
151            id_hash: Hex(x.id_hash),
152            kept_by_block: x.kept_by_block,
153            last_failed_height: x.last_failed_height,
154            last_failed_id_hash: Hex(x.last_failed_id_hash),
155            last_relayed_time: x.last_relayed_time,
156            max_used_block_height: x.max_used_block_height,
157            max_used_block_id_hash: Hex(x.max_used_block_id_hash),
158            receive_time: x.receive_time,
159            relayed: x.relayed,
160            tx_blob: HexVec(x.tx_blob),
161            tx_json: x.tx_json,
162            weight: x.weight,
163        }
164    }
165}
166
167impl From<SpentKeyImageInfo> for crate::misc::SpentKeyImageInfo {
168    fn from(x: SpentKeyImageInfo) -> Self {
169        Self {
170            id_hash: Hex(x.id_hash),
171            txs_hashes: x.txs_hashes.into_iter().map(Hex).collect(),
172        }
173    }
174}
175
176impl From<crate::misc::OutKeyBin> for crate::misc::OutKey {
177    fn from(x: crate::misc::OutKeyBin) -> Self {
178        Self {
179            key: Hex(x.key),
180            mask: Hex(x.mask),
181            unlocked: x.unlocked,
182            height: x.height,
183            txid: if x.txid == [0; 32] {
184                HexVec::new()
185            } else {
186                HexVec::from(x.txid)
187            },
188        }
189    }
190}