reth_network/session/
types.rs

1//! Shared types for network sessions.
2
3use alloy_primitives::B256;
4use parking_lot::RwLock;
5use reth_eth_wire::BlockRangeUpdate;
6use std::{
7    ops::RangeInclusive,
8    sync::{
9        atomic::{AtomicU64, Ordering},
10        Arc,
11    },
12};
13
14/// Information about the range of blocks available from a peer.
15///
16/// This represents the announced `eth69`
17/// [`BlockRangeUpdate`] of a peer.
18#[derive(Debug, Clone)]
19pub struct BlockRangeInfo {
20    /// The inner range information.
21    inner: Arc<BlockRangeInfoInner>,
22}
23
24impl BlockRangeInfo {
25    /// Creates a new range information.
26    pub fn new(earliest: u64, latest: u64, latest_hash: B256) -> Self {
27        Self {
28            inner: Arc::new(BlockRangeInfoInner {
29                earliest: AtomicU64::new(earliest),
30                latest: AtomicU64::new(latest),
31                latest_hash: RwLock::new(latest_hash),
32            }),
33        }
34    }
35
36    /// Returns true if the block number is within the range of blocks available from the peer.
37    pub fn contains(&self, block_number: u64) -> bool {
38        self.range().contains(&block_number)
39    }
40
41    /// Returns the range of blocks available from the peer.
42    pub fn range(&self) -> RangeInclusive<u64> {
43        let earliest = self.earliest();
44        let latest = self.latest();
45        RangeInclusive::new(earliest, latest)
46    }
47
48    /// Returns the earliest block number available from the peer.
49    pub fn earliest(&self) -> u64 {
50        self.inner.earliest.load(Ordering::Relaxed)
51    }
52
53    /// Returns the latest block number available from the peer.
54    pub fn latest(&self) -> u64 {
55        self.inner.latest.load(Ordering::Relaxed)
56    }
57
58    /// Returns the latest block hash available from the peer.
59    pub fn latest_hash(&self) -> B256 {
60        *self.inner.latest_hash.read()
61    }
62
63    /// Updates the range information.
64    pub fn update(&self, earliest: u64, latest: u64, latest_hash: B256) {
65        self.inner.earliest.store(earliest, Ordering::Relaxed);
66        self.inner.latest.store(latest, Ordering::Relaxed);
67        *self.inner.latest_hash.write() = latest_hash;
68    }
69
70    /// Converts the current range information to an Eth69 [`BlockRangeUpdate`] message.
71    pub fn to_message(&self) -> BlockRangeUpdate {
72        BlockRangeUpdate {
73            earliest: self.earliest(),
74            latest: self.latest(),
75            latest_hash: self.latest_hash(),
76        }
77    }
78}
79
80/// Inner structure containing the range information with atomic and thread-safe fields.
81#[derive(Debug)]
82pub(crate) struct BlockRangeInfoInner {
83    /// The earliest block which is available.
84    earliest: AtomicU64,
85    /// The latest block which is available.
86    latest: AtomicU64,
87    /// Latest available block's hash.
88    latest_hash: RwLock<B256>,
89}