Skip to content

Commit 74427ad

Browse files
committed
Refactor constants, server info & other clean ups
1 parent 5f39b51 commit 74427ad

File tree

16 files changed

+642
-704
lines changed

16 files changed

+642
-704
lines changed

node/src/bin/space-cli.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
extern crate core;
22

3-
use std::fs;
4-
use std::path::PathBuf;
3+
use std::{fs, path::PathBuf};
4+
55
use base64::{prelude::BASE64_STANDARD, Engine};
66
use clap::{Parser, Subcommand};
77
use jsonrpsee::{
@@ -17,15 +17,14 @@ use protocol::{
1717
};
1818
use serde::{Deserialize, Serialize};
1919
use spaced::{
20-
config::ExtendedNetwork,
20+
config::{default_spaces_rpc_port, ExtendedNetwork},
2121
rpc::{
2222
BidParams, ExecuteParams, OpenParams, RegisterParams, RpcClient, RpcWalletRequest,
2323
RpcWalletTxBuilder, SendCoinsParams, TransferSpacesParams,
2424
},
2525
store::Sha256,
2626
wallets::AddressKind,
2727
};
28-
use spaced::config::default_spaces_rpc_port;
2928

3029
#[derive(Parser, Debug)]
3130
#[command(version, about, long_about = None)]
@@ -422,8 +421,8 @@ async fn handle_commands(
422421
cli.client.wallet_load(name).await?;
423422
}
424423
Commands::ImportWallet { path } => {
425-
let content = fs::read_to_string(path)
426-
.map_err(|e| ClientError::Custom(e.to_string()))?;
424+
let content =
425+
fs::read_to_string(path).map_err(|e| ClientError::Custom(e.to_string()))?;
427426
cli.client.wallet_import(content).await?;
428427
}
429428
Commands::ExportWallet { name } => {

node/src/bin/spaced.rs

Lines changed: 109 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,35 @@ use std::sync::Arc;
22

33
use anyhow::anyhow;
44
use env_logger::Env;
5-
use log::{error, info};
5+
use log::error;
66
use spaced::{
77
config::{safe_exit, Args},
8-
rpc::{AsyncChainState, RpcServerImpl, WalletManager},
8+
rpc::{AsyncChainState, LoadedWallet, RpcServerImpl, WalletManager},
99
source::BitcoinBlockSource,
1010
store,
11+
sync::Spaced,
1112
wallets::RpcWallet,
1213
};
1314
use store::LiveSnapshot;
1415
use tokio::{
15-
select,
1616
sync::{broadcast, mpsc},
17-
task::JoinHandle,
18-
try_join,
17+
task::{JoinHandle, JoinSet},
1918
};
2019

2120
#[tokio::main]
2221
async fn main() {
23-
match start().await {
22+
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
23+
let sigterm = tokio::signal::ctrl_c();
24+
25+
let mut app = Composer::new();
26+
let shutdown = app.shutdown.clone();
27+
28+
tokio::spawn(async move {
29+
sigterm.await.expect("could not listen for shutdown");
30+
let _ = shutdown.send(());
31+
});
32+
33+
match app.run().await {
2434
Ok(_) => {}
2535
Err(e) => {
2636
error!("{}", e.to_string());
@@ -29,134 +39,115 @@ async fn main() {
2939
}
3040
}
3141

32-
async fn start() -> anyhow::Result<()> {
33-
env_logger::Builder::from_env(Env::default().default_filter_or("info"))
34-
.format_timestamp(None)
35-
.init();
36-
37-
let sigint = tokio::signal::ctrl_c();
38-
39-
let mut spaced = Args::configure()?;
40-
let network = spaced.network;
41-
let (shutdown_sender, _) = broadcast::channel(1);
42-
43-
let mempool = spaced.mempool.clone();
44-
let params = spaced.params;
45-
46-
let wallet_chain_state = spaced.chain.state.clone();
47-
48-
let (async_chain_state, async_chain_state_handle) = create_async_store(
49-
spaced.chain.state.clone(),
50-
spaced.block_index.as_ref().map(|index| index.state.clone()),
51-
shutdown_sender.subscribe(),
52-
)
53-
.await;
54-
55-
let (wallet_loader_tx, wallet_loader_rx) = mpsc::channel(4);
56-
let wallet_manager = WalletManager {
57-
data_dir: spaced.data_dir.join("wallets"),
58-
network: spaced.network,
59-
rpc: spaced.rpc.clone(),
60-
params,
61-
wallet_loader: wallet_loader_tx,
62-
wallets: Arc::new(Default::default()),
63-
};
64-
65-
let rpc_server = RpcServerImpl::new(async_chain_state.clone(), wallet_manager);
66-
67-
let rpc_task_server = rpc_server.clone();
68-
let rpc_task_shutdown = shutdown_sender.clone();
69-
let rpc_server_bind = spaced.bind.clone();
70-
let rpc_handle = rpc_task_server.listen(rpc_server_bind, rpc_task_shutdown);
71-
72-
let spaced_shutdown_sender = shutdown_sender.clone();
73-
74-
let (spaced_sender, spaced_receiver) = tokio::sync::oneshot::channel();
75-
let rpc = spaced.rpc.clone();
76-
let rpc2 = spaced.rpc.clone();
77-
std::thread::spawn(move || {
78-
let source = BitcoinBlockSource::new(rpc);
79-
_ = spaced_sender.send(spaced.protocol_sync(source, spaced_shutdown_sender));
80-
});
42+
struct Composer {
43+
shutdown: broadcast::Sender<()>,
44+
services: JoinSet<anyhow::Result<()>>,
45+
}
8146

82-
let wallet_service_shutdown = shutdown_sender.clone();
83-
let wallet_service = RpcWallet::service(
84-
network,
85-
mempool,
86-
rpc2,
87-
wallet_chain_state,
88-
wallet_loader_rx,
89-
wallet_service_shutdown,
90-
);
91-
92-
let signal = shutdown_sender.clone();
93-
tokio::spawn(async move {
94-
_ = sigint.await;
95-
_ = signal.send(());
96-
});
47+
impl Composer {
48+
fn new() -> Self {
49+
let (shutdown, _) = broadcast::channel(1);
50+
Self {
51+
shutdown,
52+
services: JoinSet::new(),
53+
}
54+
}
55+
56+
async fn setup_rpc_wallet(&mut self, spaced: &Spaced, rx: mpsc::Receiver<LoadedWallet>) {
57+
let wallet_service = RpcWallet::service(
58+
spaced.network,
59+
spaced.rpc.clone(),
60+
spaced.chain.state.clone(),
61+
rx,
62+
self.shutdown.clone(),
63+
);
64+
65+
self.services.spawn(async move {
66+
wallet_service
67+
.await
68+
.map_err(|e| anyhow!("Wallet service error: {}", e))
69+
});
70+
}
9771

98-
let shutdown_result = try_join!(
99-
async {
100-
let res = spaced_receiver.await;
101-
_ = shutdown_sender.send(());
102-
if let Ok(res) = res {
103-
if let Err(e) = res {
104-
error!("Protocol sync: {}", e);
105-
return Err(anyhow!("Protocol sync error: {}", e));
106-
}
107-
}
108-
Ok(())
109-
},
110-
async {
111-
let res = rpc_handle.await;
112-
_ = shutdown_sender.send(());
113-
if let Err(e) = res {
114-
error!("RPC Server: {}", e);
115-
return Err(anyhow!("RPC Server error: {}", e));
116-
}
117-
Ok(())
118-
},
119-
async {
120-
let res = wallet_service.await;
121-
_ = shutdown_sender.send(());
122-
if let Err(e) = res {
123-
error!("Wallet service: {}", e);
124-
return Err(anyhow!("Wallet service error: {}", e));
125-
}
126-
Ok(())
127-
},
128-
async {
129-
let res = async_chain_state_handle
72+
async fn setup_rpc_services(&mut self, spaced: &Spaced) {
73+
let (wallet_loader_tx, wallet_loader_rx) = mpsc::channel(1);
74+
75+
let wallet_manager = WalletManager {
76+
data_dir: spaced.data_dir.join("wallets"),
77+
network: spaced.network,
78+
rpc: spaced.rpc.clone(),
79+
wallet_loader: wallet_loader_tx,
80+
wallets: Arc::new(Default::default()),
81+
};
82+
83+
let (async_chain_state, async_chain_state_handle) = create_async_store(
84+
spaced.chain.state.clone(),
85+
spaced.block_index.as_ref().map(|index| index.state.clone()),
86+
self.shutdown.subscribe(),
87+
)
88+
.await;
89+
90+
self.services.spawn(async {
91+
async_chain_state_handle
13092
.await
131-
.map_err(|e| anyhow!("Async chain state error: {}", e));
132-
_ = shutdown_sender.send(());
133-
res
93+
.map_err(|e| anyhow!("Chain state error: {}", e))
94+
});
95+
let rpc_server = RpcServerImpl::new(async_chain_state.clone(), wallet_manager);
96+
97+
let bind = spaced.bind.clone();
98+
let shutdown = self.shutdown.clone();
99+
100+
self.services.spawn(async move {
101+
rpc_server
102+
.listen(bind, shutdown)
103+
.await
104+
.map_err(|e| anyhow!("RPC Server error: {}", e))
105+
});
106+
107+
self.setup_rpc_wallet(spaced, wallet_loader_rx).await;
108+
}
109+
110+
async fn setup_sync_service(&mut self, mut spaced: Spaced) {
111+
let (spaced_sender, spaced_receiver) = tokio::sync::oneshot::channel();
112+
113+
let shutdown = self.shutdown.clone();
114+
let rpc = spaced.rpc.clone();
115+
116+
std::thread::spawn(move || {
117+
let source = BitcoinBlockSource::new(rpc);
118+
_ = spaced_sender.send(spaced.protocol_sync(source, shutdown));
119+
});
120+
121+
self.services.spawn(async move {
122+
spaced_receiver
123+
.await?
124+
.map_err(|e| anyhow!("Protocol sync error: {}", e))
125+
});
126+
}
127+
128+
async fn run(&mut self) -> anyhow::Result<()> {
129+
let spaced = Args::configure()?;
130+
self.setup_rpc_services(&spaced).await;
131+
self.setup_sync_service(spaced).await;
132+
133+
while let Some(res) = self.services.join_next().await {
134+
res??
134135
}
135-
);
136136

137-
if !shutdown_result.is_ok() {
138-
safe_exit(1);
137+
Ok(())
139138
}
140-
Ok(())
141139
}
142140

143141
async fn create_async_store(
144142
chain_state: LiveSnapshot,
145143
block_index: Option<LiveSnapshot>,
146-
mut shutdown: broadcast::Receiver<()>,
144+
shutdown: broadcast::Receiver<()>,
147145
) -> (AsyncChainState, JoinHandle<()>) {
148146
let (tx, rx) = mpsc::channel(32);
149147
let async_store = AsyncChainState::new(tx);
150148

151149
let handle = tokio::spawn(async move {
152-
select! {
153-
_ = AsyncChainState::handler(chain_state, block_index, rx) => {
154-
// Handler completed normally
155-
}
156-
Ok(_) = shutdown.recv() => {
157-
info!("Shutting down database...");
158-
}
159-
}
150+
AsyncChainState::handler(chain_state, block_index, rx, shutdown).await
160151
});
161152
(async_store, handle)
162153
}

node/src/config.rs

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
use std::{
2-
collections::{BTreeMap, HashMap, HashSet},
2+
collections::{HashMap, HashSet},
33
env,
44
ffi::OsString,
55
fmt::Display,
66
fs,
77
net::{IpAddr, SocketAddr},
88
path::PathBuf,
9-
sync::{Arc, RwLock},
109
};
1110

1211
use clap::{
@@ -23,7 +22,7 @@ use toml::Value;
2322
use crate::{
2423
source::{BitcoinRpc, BitcoinRpcAuth},
2524
store::{LiveStore, Store},
26-
sync::{Mempool, Spaced},
25+
sync::Spaced,
2726
};
2827

2928
const RPC_OPTIONS: &str = "RPC Server Options";
@@ -75,6 +74,7 @@ pub struct Args {
7574
}
7675

7776
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, ValueEnum, Serialize, Deserialize)]
77+
#[serde(rename_all = "lowercase")]
7878
pub enum ExtendedNetwork {
7979
Mainnet,
8080
Testnet,
@@ -142,7 +142,7 @@ impl Args {
142142
})
143143
.collect();
144144

145-
let params = Spaced::params(args.chain);
145+
let genesis = Spaced::genesis(args.chain);
146146
let bitcoin_rpc_auth = if let Some(cookie) = args.bitcoin_rpc_cookie {
147147
let cookie = std::fs::read_to_string(cookie)?;
148148
BitcoinRpcAuth::Cookie(cookie)
@@ -161,34 +161,28 @@ impl Args {
161161

162162
let chain_store = Store::open(data_dir.join("protocol.sdb"))?;
163163
let chain = LiveStore {
164-
state: chain_store.begin(&params)?,
164+
state: chain_store.begin(&genesis)?,
165165
store: chain_store,
166166
};
167167

168168
let block_index = match args.block_index {
169169
true => {
170170
let block_store = Store::open(data_dir.join("blocks.sdb"))?;
171171
Some(LiveStore {
172-
state: block_store.begin(&params).expect("begin block index"),
172+
state: block_store.begin(&genesis).expect("begin block index"),
173173
store: block_store,
174174
})
175175
}
176176
false => None,
177177
};
178178

179-
let tx_count = chain.state.metadata.read().expect("read").tx_count;
180179
Ok(Spaced {
181180
network: args.chain,
182-
params,
183181
rpc,
184182
data_dir,
185183
bind: rpc_bind_addresses,
186184
chain,
187185
block_index,
188-
mempool: Mempool {
189-
opens: Arc::new(RwLock::new(BTreeMap::new())),
190-
},
191-
tx_count,
192186
})
193187
}
194188

@@ -249,7 +243,7 @@ fn default_bitcoin_rpc_url(network: &ExtendedNetwork) -> &'static str {
249243
ExtendedNetwork::Mainnet => "http://127.0.0.1:8332",
250244
ExtendedNetwork::Testnet4 => "http://127.0.0.1:48332",
251245
ExtendedNetwork::Signet => "http://127.0.0.1:38332",
252-
ExtendedNetwork::Testnet => "http://127.0.0.1:18332",
246+
ExtendedNetwork::Testnet => "http://127.0.0.1:18332",
253247
ExtendedNetwork::Regtest => "http://127.0.0.1:18443",
254248
}
255249
}
@@ -362,4 +356,3 @@ pub fn default_spaces_rpc_port(chain: &ExtendedNetwork) -> u16 {
362356
ExtendedNetwork::Regtest => 7218,
363357
}
364358
}
365-

0 commit comments

Comments
 (0)