cuprate_wire/p2p/
common.rs

1// Rust Levin Library
2// Written in 2023 by
3//   Cuprate Contributors
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14//
15
16//! Common types that are used across multiple messages.
17
18use bitflags::bitflags;
19
20use cuprate_epee_encoding::epee_object;
21use cuprate_helper::map::split_u128_into_low_high_bits;
22pub use cuprate_types::{BlockCompleteEntry, PrunedTxBlobEntry, TransactionBlobs};
23
24use crate::NetworkAddress;
25
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub struct PeerSupportFlags(u32);
28
29bitflags! {
30    impl PeerSupportFlags: u32 {
31        const FLUFFY_BLOCKS = 0b0000_0001;
32        const _ = !0;
33    }
34}
35
36impl From<u32> for PeerSupportFlags {
37    fn from(value: u32) -> Self {
38        Self(value)
39    }
40}
41
42impl From<PeerSupportFlags> for u32 {
43    fn from(value: PeerSupportFlags) -> Self {
44        value.0
45    }
46}
47
48impl<'a> From<&'a PeerSupportFlags> for &'a u32 {
49    fn from(value: &'a PeerSupportFlags) -> Self {
50        &value.0
51    }
52}
53
54/// Basic Node Data, information on the connected peer
55#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct BasicNodeData {
57    /// Port
58    pub my_port: u32,
59    /// The Network Id
60    // We don't use ByteArray here to allow users to keep this data long term.
61    pub network_id: [u8; 16],
62    /// Peer ID
63    pub peer_id: u64,
64    /// The Peers Support Flags
65    /// (If this is not in the message the default is 0)
66    pub support_flags: PeerSupportFlags,
67    /// RPC Port
68    /// (If this is not in the message the default is 0)
69    pub rpc_port: u16,
70    /// RPC Credits Per Hash
71    /// (If this is not in the message the default is 0)
72    pub rpc_credits_per_hash: u32,
73}
74
75epee_object! {
76    BasicNodeData,
77    my_port: u32,
78    network_id: [u8; 16],
79    peer_id: u64,
80    support_flags: PeerSupportFlags as u32 = 0_u32,
81    rpc_port: u16 = 0_u16,
82    rpc_credits_per_hash: u32 = 0_u32,
83}
84
85/// Core Sync Data, information on the sync state of a peer
86#[derive(Debug, Clone, PartialEq, Eq)]
87pub struct CoreSyncData {
88    /// Cumulative Difficulty Low
89    /// The lower 64 bits of the 128 bit cumulative difficulty
90    pub cumulative_difficulty: u64,
91    /// Cumulative Difficulty High
92    /// The upper 64 bits of the 128 bit cumulative difficulty
93    pub cumulative_difficulty_top64: u64,
94    /// Current Height of the peer
95    pub current_height: u64,
96    /// Pruning Seed of the peer
97    /// (If this is not in the message the default is 0)
98    pub pruning_seed: u32,
99    /// Hash of the top block
100    // We don't use ByteArray here to allow users to keep this data long term.
101    pub top_id: [u8; 32],
102    /// Version of the top block
103    pub top_version: u8,
104}
105
106epee_object! {
107    CoreSyncData,
108    cumulative_difficulty: u64,
109    cumulative_difficulty_top64: u64 = 0_u64,
110    current_height: u64,
111    pruning_seed: u32 = 0_u32,
112    top_id: [u8; 32],
113    top_version: u8 = 0_u8,
114}
115
116impl CoreSyncData {
117    pub const fn new(
118        cumulative_difficulty_128: u128,
119        current_height: u64,
120        pruning_seed: u32,
121        top_id: [u8; 32],
122        top_version: u8,
123    ) -> Self {
124        let (cumulative_difficulty, cumulative_difficulty_top64) =
125            split_u128_into_low_high_bits(cumulative_difficulty_128);
126
127        Self {
128            cumulative_difficulty,
129            cumulative_difficulty_top64,
130            current_height,
131            pruning_seed,
132            top_id,
133            top_version,
134        }
135    }
136    /// Returns the 128 bit cumulative difficulty of the peers blockchain
137    pub fn cumulative_difficulty(&self) -> u128 {
138        let mut ret: u128 = self.cumulative_difficulty_top64.into();
139        ret <<= 64;
140        ret | (Into::<u128>::into(self.cumulative_difficulty))
141    }
142}
143
144/// `PeerListEntryBase`, information kept on a peer which will be entered
145/// in a peer list/store.
146#[derive(Clone, Copy, Debug, Eq, PartialEq)]
147pub struct PeerListEntryBase {
148    /// The Peer Address
149    pub adr: NetworkAddress,
150    /// The Peer ID
151    pub id: u64,
152    /// The last Time The Peer Was Seen
153    pub last_seen: i64,
154    /// The Pruning Seed
155    pub pruning_seed: u32,
156    /// The RPC port
157    pub rpc_port: u16,
158    /// The RPC credits per hash
159    pub rpc_credits_per_hash: u32,
160}
161
162epee_object! {
163    PeerListEntryBase,
164    adr: NetworkAddress,
165    id: u64,
166    last_seen: i64 = 0_i64,
167    pruning_seed: u32 = 0_u32,
168    rpc_port: u16 = 0_u16,
169    rpc_credits_per_hash: u32 = 0_u32,
170}
171
172#[cfg(test)]
173mod tests {
174
175    use super::CoreSyncData;
176
177    #[test]
178    fn core_sync_cumulative_difficulty() {
179        let core_sync = CoreSyncData::new(u128::MAX, 80085, 200, [0; 32], 21);
180        assert_eq!(core_sync.cumulative_difficulty(), u128::MAX);
181        let core_sync = CoreSyncData::new(21, 80085, 200, [0; 32], 21);
182        assert_eq!(core_sync.cumulative_difficulty(), 21);
183    }
184}