snap_coin/full_node/
node_state.rs1use serde::{Deserialize, Serialize};
2use std::{
3 collections::{HashMap, VecDeque},
4 net::SocketAddr,
5 sync::Arc,
6};
7use tokio::sync::{
8 Mutex, RwLock, broadcast,
9 watch::{self, Ref},
10};
11
12use crate::{
13 core::{
14 block::Block,
15 difficulty::calculate_live_transaction_difficulty,
16 transaction::{Transaction, TransactionId},
17 },
18 crypto::Hash,
19 full_node::mempool::MemPool,
20 node::peer::PeerHandle,
21};
22
23pub type SharedNodeState = Arc<NodeState>;
24
25pub struct NodeState {
26 pub connected_peers: RwLock<HashMap<SocketAddr, PeerHandle>>,
27 pub mempool: MemPool,
28 pub is_syncing: RwLock<bool>,
29 pub chain_events: broadcast::Sender<ChainEvent>,
30 pub adding_block: Mutex<()>,
31 last_seen_block_reader: watch::Receiver<Hash>,
32 last_seen_block_writer: watch::Sender<Hash>,
33 last_seen_transactions_reader: watch::Receiver<VecDeque<TransactionId>>,
34 last_seen_transactions_writer: watch::Sender<VecDeque<TransactionId>>,
35}
36
37impl NodeState {
38 pub fn new_empty() -> SharedNodeState {
39 let (last_seen_block_writer, last_seen_block_reader) =
40 watch::channel(Hash::new_from_buf([0u8; 32]));
41 let (last_seen_transactions_writer, last_seen_transactions_reader) =
42 watch::channel(VecDeque::new());
43
44 Arc::new(NodeState {
45 connected_peers: RwLock::new(HashMap::new()),
46 mempool: MemPool::new(),
47 is_syncing: RwLock::new(false),
48 chain_events: broadcast::channel(64).0,
49 adding_block: Mutex::new(()),
50 last_seen_block_reader,
51 last_seen_block_writer,
52 last_seen_transactions_reader,
53 last_seen_transactions_writer,
54 })
55 }
56
57 pub fn last_seen_block(&self) -> Hash {
59 self.last_seen_block_reader.borrow().clone()
60 }
61
62 pub fn set_last_seen_block(&self, hash: Hash) {
64 let _ = self.last_seen_block_writer.send(hash);
65 }
66
67 pub fn last_seen_transactions(&self) -> Ref<'_, VecDeque<TransactionId>> {
69 self.last_seen_transactions_reader.borrow()
70 }
71
72 pub fn add_last_seen_transaction(&self, tx_id: TransactionId) {
74 let mut transactions: VecDeque<TransactionId> =
75 self.last_seen_transactions_reader.borrow().clone();
76
77 if !transactions.contains(&tx_id) {
79 transactions.push_back(tx_id);
80
81 if transactions.len() > 500 {
83 transactions.pop_front(); }
85
86 let _ = self.last_seen_transactions_writer.send(transactions);
87 }
88 }
89
90 pub async fn get_live_transaction_difficulty(
91 &self,
92 transaction_difficulty: [u8; 32],
93 ) -> [u8; 32] {
94 calculate_live_transaction_difficulty(
95 &transaction_difficulty,
96 self.mempool.mempool_size().await,
97 )
98 }
99}
100
101#[derive(Serialize, Deserialize, Clone)]
102pub enum ChainEvent {
103 Block { block: Block },
104 Transaction { transaction: Transaction },
105 TransactionExpiration { transaction: TransactionId },
106}