Skip to content

Commit e9db7ac

Browse files
committed
Add docs to (almost)all public code in JDS
Adding docs to JDS public modules and more improve internal docs around networking and state management through channels.
1 parent ea139a7 commit e9db7ac

File tree

5 files changed

+71
-10
lines changed

5 files changed

+71
-10
lines changed

roles/jd-server/src/lib/error.rs

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1+
use crate::mempool::error::JdsMempoolError;
2+
use roles_logic_sv2::parsers::Mining;
13
use std::{
24
convert::From,
35
fmt::Debug,
46
sync::{MutexGuard, PoisonError},
57
};
68

7-
use roles_logic_sv2::parsers::Mining;
8-
9-
use crate::mempool::error::JdsMempoolError;
10-
9+
/// Represents an error that can occur in the JDS.
1110
#[derive(std::fmt::Debug)]
1211
pub enum JdsError {
1312
Io(std::io::Error),

roles/jd-server/src/lib/job_declarator/mod.rs

+12
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ pub struct AddTrasactionsToMempool {
4747
pub sender_add_txs_to_mempool: Sender<AddTrasactionsToMempoolInner>,
4848
}
4949

50+
/// Represents a downstream connection.
51+
///
52+
/// This struct is used in order to give a representation to each downstream connection that the
53+
/// JDS has.
5054
#[derive(Debug)]
5155
pub struct JobDeclaratorDownstream {
5256
async_mining_allowed: bool,
@@ -72,6 +76,7 @@ pub struct JobDeclaratorDownstream {
7276
}
7377

7478
impl JobDeclaratorDownstream {
79+
/// Create a new [`JobDeclaratorDownstream`] instance.
7580
pub fn new(
7681
async_mining_allowed: bool,
7782
receiver: Receiver<EitherFrame>,
@@ -193,6 +198,7 @@ impl JobDeclaratorDownstream {
193198
known_transactions
194199
}
195200

201+
/// Send a message to the downstream connection.
196202
pub async fn send(
197203
self_mutex: Arc<Mutex<Self>>,
198204
message: roles_logic_sv2::parsers::JobDeclaration<'static>,
@@ -202,6 +208,8 @@ impl JobDeclaratorDownstream {
202208
sender.send(sv2_frame.into()).await.map_err(|_| ())?;
203209
Ok(())
204210
}
211+
212+
/// Start the downstream connection handler.
205213
pub fn start(
206214
self_mutex: Arc<Mutex<Self>>,
207215
tx_status: status::Sender,
@@ -425,9 +433,13 @@ fn _get_random_token() -> B0255<'static> {
425433
inner.to_vec().try_into().unwrap()
426434
}
427435

436+
/// Represents a server that JDS uses to communicate with downstream(usually JDC) connections.
428437
pub struct JobDeclarator {}
429438

430439
impl JobDeclarator {
440+
/// Start a TCP server that listens for incoming connections.
441+
///
442+
/// The server will accept incoming connections and spawn a new task for each new one.
431443
pub async fn start(
432444
config: JobDeclaratorServerConfig,
433445
status_tx: crate::status::Sender,

roles/jd-server/src/lib/mempool/error.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use rpc_sv2::mini_rpc_client::RpcError;
22
use std::{convert::From, sync::PoisonError};
33
use tracing::{error, warn};
44

5+
/// Represents the possible errors that can occur in the JDS mempool.
56
#[derive(Debug)]
67
pub enum JdsMempoolError {
78
EmptyMempool,

roles/jd-server/src/lib/mempool/mod.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ pub struct TransactionWithHash {
1515
pub tx: Option<(Transaction, u32)>,
1616
}
1717

18+
/// A struct that represents the mempool version of JDS.
19+
///
20+
/// This struct is used in order to maintain an internal copy of the mempool of the JDS. This is
21+
/// useful in order to keep track of the transactions that are in the mempool and to be able to
22+
/// provide the transactions to JDCs when they request them.
1823
#[derive(Clone, Debug)]
1924
pub struct JDsMempool {
2025
pub mempool: HashMap<Txid, Option<(Transaction, u32)>>,
@@ -24,6 +29,9 @@ pub struct JDsMempool {
2429
}
2530

2631
impl JDsMempool {
32+
/// Return Bitcoin node RPC client.
33+
///
34+
/// This will return none if the URL is not an http or https URL.
2735
pub fn get_client(&self) -> Option<mini_rpc_client::MiniRpcClient> {
2836
let url = self.url.as_str();
2937
if url.contains("http") {
@@ -43,6 +51,7 @@ impl JDsMempool {
4351
tx_list_
4452
}
4553

54+
/// Create a new [`JDsMempool`] instance.
4655
pub fn new(
4756
url: String,
4857
username: String,
@@ -59,17 +68,15 @@ impl JDsMempool {
5968
}
6069
}
6170

62-
/// Checks if the rpc client is accessible.
71+
/// Checks if Bitcoin node RPC client is accessible.
6372
pub async fn health(self_: Arc<Mutex<Self>>) -> Result<(), JdsMempoolError> {
6473
let client = self_
6574
.safe_lock(|a| a.get_client())?
6675
.ok_or(JdsMempoolError::NoClient)?;
6776
client.health().await.map_err(JdsMempoolError::Rpc)
6877
}
6978

70-
// this functions fill in the mempool the transactions with the given txid and insert the given
71-
// transactions. The ids are for the transactions that are already known to the node, the
72-
// unknown transactions are provided directly as a vector
79+
/// Publish transactions to the Bitcoin node.
7380
pub async fn add_tx_data_to_mempool(
7481
self_: Arc<Mutex<Self>>,
7582
add_txs_to_mempool_inner: AddTrasactionsToMempoolInner,
@@ -123,6 +130,7 @@ impl JDsMempool {
123130
Ok(())
124131
}
125132

133+
/// Get the latest version of the mempool from the Bitcoin node and update the internal copy.
126134
pub async fn update_mempool(self_: Arc<Mutex<Self>>) -> Result<(), JdsMempoolError> {
127135
let client = self_
128136
.safe_lock(|x| x.get_client())?
@@ -155,6 +163,7 @@ impl JDsMempool {
155163
}
156164
}
157165

166+
/// Handle a new block received from downstream connections.
158167
pub async fn on_submit(self_: Arc<Mutex<Self>>) -> Result<(), JdsMempoolError> {
159168
let new_block_receiver: Receiver<String> =
160169
self_.safe_lock(|x| x.new_block_receiver.clone())?;
@@ -171,6 +180,7 @@ impl JDsMempool {
171180
Ok(())
172181
}
173182

183+
/// will be deprecated soon
174184
pub fn to_short_ids(&self, nonce: u64) -> Option<HashMap<[u8; 6], TransactionWithHash>> {
175185
let mut ret = HashMap::new();
176186
for tx in &self.mempool {

roles/jd-server/src/lib/mod.rs

+41-2
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,56 @@ pub type Message = JdsMessages<'static>;
2020
pub type StdFrame = StandardSv2Frame<Message>;
2121
pub type EitherFrame = StandardEitherFrame<Message>;
2222

23+
/// Represents the Job Declarator Server role in a Stratum V2 setup.
24+
///
25+
/// Stratum V2 protocol separates the Job Declaration role into two parts: the Job Declarator Server
26+
/// (JDS) and the Job Declarator Client (JDC).
27+
///
28+
/// JDS is responsible for maintaining a copy of the mempool by requesting updates from a Bitcoin
29+
/// node through the RPC interface. It is also acting as an upstream for JDC, allowing it to submit
30+
/// solutions and verify transactions.
31+
///
32+
/// JDS is usually run by a mining pool operator.
2333
#[derive(Debug, Clone)]
2434
pub struct JobDeclaratorServer {
2535
config: JobDeclaratorServerConfig,
2636
}
2737

2838
impl JobDeclaratorServer {
39+
/// Creates a new instance of the Job Declarator Server.
2940
pub fn new(config: JobDeclaratorServerConfig) -> Result<Self, Box<JdsError>> {
30-
let url = config.core_rpc_url().to_string() + ":" + &config.core_rpc_port().to_string();
41+
let url =
42+
config.core_rpc_url().to_string() + ":" + &config.core_rpc_port().clone().to_string();
3143
if !is_valid_url(&url) {
3244
return Err(Box::new(JdsError::InvalidRPCUrl));
3345
}
3446
Ok(Self { config })
3547
}
48+
/// Starts the Job Declarator Server.
49+
///
50+
/// This will start the Job Declarator Server and run it until it is interrupted.
51+
///
52+
/// JDS initialization starts with initialization of the mempool, which is done by connecting to
53+
/// Bitcoin node. An async job is then started in order to update the mempool at regular
54+
/// intervals. After that, JDS will start a TCP server to listen for incoming connections
55+
/// from JDC(s).
56+
///
57+
/// In total JDS maintains three channels:
58+
/// - `new_block_receiver` is used to manage new blocks found by downstreams(JDCs).
59+
/// - `status_rx` is used to manage JDS internal state.
60+
/// - `receiver_add_txs_to_mempool` is used to update local mempool with transactions coming
61+
/// from JDC(s).
3662
pub async fn start(&self) -> Result<(), JdsError> {
3763
let config = self.config.clone();
3864
let url = config.core_rpc_url().to_string() + ":" + &config.core_rpc_port().to_string();
3965
let username = config.core_rpc_user();
4066
let password = config.core_rpc_pass();
41-
// TODO should we manage what to do when the limit is reaced?
67+
// This channel is managing new blocks found by downstreams(JDCs).
68+
// JDS will listen for new blocks at `new_block_receiver` and update the mempool
69+
// accordingly.
4270
let (new_block_sender, new_block_receiver): (Sender<String>, Receiver<String>) =
4371
bounded(10);
72+
// new empty mempool
4473
let mempool = Arc::new(Mutex::new(mempool::JDsMempool::new(
4574
url.clone(),
4675
username.to_string(),
@@ -50,16 +79,19 @@ impl JobDeclaratorServer {
5079
let mempool_update_interval = config.mempool_update_interval();
5180
let mempool_cloned_ = mempool.clone();
5281
let mempool_cloned_1 = mempool.clone();
82+
// make sure we can access bitcoin node through RPC
5383
if let Err(e) = mempool::JDsMempool::health(mempool_cloned_1.clone()).await {
5484
error!("{:?}", e);
5585
return Err(JdsError::MempoolError(e));
5686
}
87+
// This channel is managing JDS internal state.
5788
let (status_tx, status_rx) = unbounded();
5889
let sender = status::Sender::Downstream(status_tx.clone());
5990
let mut last_empty_mempool_warning =
6091
std::time::Instant::now().sub(std::time::Duration::from_secs(60));
6192

6293
let sender_update_mempool = sender.clone();
94+
// update the mempool at regular intervals
6395
task::spawn(async move {
6496
loop {
6597
let update_mempool_result: Result<(), mempool::error::JdsMempoolError> =
@@ -96,6 +128,9 @@ impl JobDeclaratorServer {
96128

97129
let mempool_cloned = mempool.clone();
98130
let sender_submit_solution = sender.clone();
131+
// * start an async job to submit solutions to the mempool
132+
// * this job will take solutions from JDC and submit them to the mempool
133+
// * the job is transferred to the mempool module via a channel(new_block_receiver/sender)
99134
task::spawn(async move {
100135
loop {
101136
let result = mempool::JDsMempool::on_submit(mempool_cloned.clone()).await;
@@ -120,7 +155,10 @@ impl JobDeclaratorServer {
120155

121156
let cloned = config.clone();
122157
let mempool_cloned = mempool.clone();
158+
// JDS will update the local mempool when a new transaction is received from JDC(s) through
159+
// this channel
123160
let (sender_add_txs_to_mempool, receiver_add_txs_to_mempool) = unbounded();
161+
// start a TCP server to listen for incoming connections from JDC(s)
124162
task::spawn(async move {
125163
JobDeclarator::start(
126164
cloned,
@@ -131,6 +169,7 @@ impl JobDeclaratorServer {
131169
)
132170
.await
133171
});
172+
// start a task to update local mempool with transactions coming from JDC(s)
134173
task::spawn(async move {
135174
loop {
136175
if let Ok(add_transactions_to_mempool) = receiver_add_txs_to_mempool.recv().await {

0 commit comments

Comments
 (0)