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//
1516//! Common types that are used across multiple messages.
1718use bitflags::bitflags;
1920use cuprate_epee_encoding::epee_object;
21use cuprate_helper::map::split_u128_into_low_high_bits;
22pub use cuprate_types::{BlockCompleteEntry, PrunedTxBlobEntry, TransactionBlobs};
2324use crate::NetworkAddress;
2526#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub struct PeerSupportFlags(u32);
2829bitflags! {
30impl PeerSupportFlags: u32 {
31const FLUFFY_BLOCKS = 0b0000_0001;
32const _ = !0;
33 }
34}
3536impl From<u32> for PeerSupportFlags {
37fn from(value: u32) -> Self {
38Self(value)
39 }
40}
4142impl From<PeerSupportFlags> for u32 {
43fn from(value: PeerSupportFlags) -> Self {
44 value.0
45}
46}
4748impl<'a> From<&'a PeerSupportFlags> for &'a u32 {
49fn from(value: &'a PeerSupportFlags) -> Self {
50&value.0
51}
52}
5354/// Basic Node Data, information on the connected peer
55#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct BasicNodeData {
57/// Port
58pub my_port: u32,
59/// The Network Id
60// We don't use ByteArray here to allow users to keep this data long term.
61pub network_id: [u8; 16],
62/// Peer ID
63pub peer_id: u64,
64/// The Peers Support Flags
65 /// (If this is not in the message the default is 0)
66pub support_flags: PeerSupportFlags,
67/// RPC Port
68 /// (If this is not in the message the default is 0)
69pub rpc_port: u16,
70/// RPC Credits Per Hash
71 /// (If this is not in the message the default is 0)
72pub rpc_credits_per_hash: u32,
73}
7475epee_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}
8485/// 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
90pub cumulative_difficulty: u64,
91/// Cumulative Difficulty High
92 /// The upper 64 bits of the 128 bit cumulative difficulty
93pub cumulative_difficulty_top64: u64,
94/// Current Height of the peer
95pub current_height: u64,
96/// Pruning Seed of the peer
97 /// (If this is not in the message the default is 0)
98pub 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.
101pub top_id: [u8; 32],
102/// Version of the top block
103pub top_version: u8,
104}
105106epee_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}
115116impl CoreSyncData {
117pub 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 {
124let (cumulative_difficulty, cumulative_difficulty_top64) =
125 split_u128_into_low_high_bits(cumulative_difficulty_128);
126127Self {
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
137pub fn cumulative_difficulty(&self) -> u128 {
138let mut ret: u128 = self.cumulative_difficulty_top64.into();
139 ret <<= 64;
140 ret | (Into::<u128>::into(self.cumulative_difficulty))
141 }
142}
143144/// `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
149pub adr: NetworkAddress,
150/// The Peer ID
151pub id: u64,
152/// The last Time The Peer Was Seen
153pub last_seen: i64,
154/// The Pruning Seed
155pub pruning_seed: u32,
156/// The RPC port
157pub rpc_port: u16,
158/// The RPC credits per hash
159pub rpc_credits_per_hash: u32,
160}
161162epee_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}
171172#[cfg(test)]
173mod tests {
174175use super::CoreSyncData;
176177#[test]
178fn core_sync_cumulative_difficulty() {
179let core_sync = CoreSyncData::new(u128::MAX, 80085, 200, [0; 32], 21);
180assert_eq!(core_sync.cumulative_difficulty(), u128::MAX);
181let core_sync = CoreSyncData::new(21, 80085, 200, [0; 32], 21);
182assert_eq!(core_sync.cumulative_difficulty(), 21);
183 }
184}