Skip to content

Commit

Permalink
Netwoking refactor, change default net addr, Reorgs, bump version num…
Browse files Browse the repository at this point in the history
…ber for release
  • Loading branch information
Ash-L2L committed May 2, 2024
1 parent b7ba358 commit ded1293
Show file tree
Hide file tree
Showing 26 changed files with 3,876 additions and 1,584 deletions.
899 changes: 487 additions & 412 deletions Cargo.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ members = [
[workspace.package]
authors = [ "Ash Manning <ash@layertwolabs.com>" ]
edition = "2021"
version = "0.6.0"
version = "0.7.0"

[workspace.dependencies.bip300301]
git = "https://github.com/Ash-L2L/bip300301.git"
rev = "43ba4d7bee075ecd2504f87b5ec2a5ba3b10cd3b"
rev = "e47a263c8cbf9c520aa80f71788ee28e9f11bb62"

[profile.release]
# lto = "fat"
1 change: 1 addition & 0 deletions app/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ strum = { version = "0.25.0", features = ["derive"] }
thiserror = "1.0.44"
tiny-bip39 = "1.0.0"
tokio = { version = "1.29.1", features = ["macros", "rt-multi-thread"] }
tokio-util = { version = "0.7.10", features = ["rt"] }
tracing = "0.1.40"
tracing-subscriber = "0.3.18"

Expand Down
97 changes: 57 additions & 40 deletions app/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ use std::{
};

use parking_lot::RwLock;
use tokio::sync::RwLock as TokioRwLock;

use plain_bitnames::{
bip300301::{bitcoin, MainClient},
format_deposit_address,
Expand All @@ -18,18 +16,11 @@ use plain_bitnames::{
},
wallet::{self, Wallet},
};
use tokio::sync::RwLock as TokioRwLock;
use tokio_util::task::LocalPoolHandle;

use crate::cli::Config;

#[derive(Clone)]
pub struct App {
pub node: Arc<Node>,
pub wallet: Arc<Wallet>,
pub miner: Arc<TokioRwLock<Miner>>,
pub utxos: Arc<RwLock<HashMap<OutPoint, FilledOutput>>>,
pub runtime: Arc<tokio::runtime::Runtime>,
}

#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("drivechain error")]
Expand All @@ -48,6 +39,16 @@ pub enum Error {
Wallet(#[from] wallet::Error),
}

#[derive(Clone)]
pub struct App {
pub node: Arc<Node>,
pub wallet: Arc<Wallet>,
pub miner: Arc<TokioRwLock<Miner>>,
pub utxos: Arc<RwLock<HashMap<OutPoint, FilledOutput>>>,
pub runtime: Arc<tokio::runtime::Runtime>,
pub local_pool: LocalPoolHandle,
}

impl App {
pub fn new(config: &Config) -> Result<Self, Error> {
// Node launches some tokio tasks for p2p networking, that is why we need a tokio runtime
Expand All @@ -66,24 +67,18 @@ impl App {
&config.main_user,
&config.main_password,
)?;
let node = runtime.block_on(async {
let node = match Node::new(
config.net_addr,
&config.datadir,
config.main_addr,
&config.main_password,
&config.main_user,
#[cfg(all(not(target_os = "windows"), feature = "zmq"))]
config.zmq_addr,
) {
Ok(node) => node,
Err(err) => return Err(err),
};
Ok(node)
})?;
let node = Arc::new(node);
let rt_guard = runtime.enter();
node.clone().run()?;
let local_pool = LocalPoolHandle::new(1);
let node = Node::new(
config.net_addr,
&config.datadir,
config.main_addr,
&config.main_password,
&config.main_user,
local_pool.clone(),
#[cfg(all(not(target_os = "windows"), feature = "zmq"))]
config.zmq_addr,
)?;
drop(rt_guard);
let utxos = {
let mut utxos = wallet.get_utxos()?;
Expand All @@ -96,18 +91,18 @@ impl App {
Arc::new(RwLock::new(utxos))
};
Ok(Self {
node,
node: Arc::new(node),
wallet: Arc::new(wallet),
miner: Arc::new(TokioRwLock::new(miner)),
utxos,
runtime: Arc::new(runtime),
local_pool,
})
}

pub fn sign_and_send(&self, tx: Transaction) -> Result<(), Error> {
let authorized_transaction = self.wallet.authorize(tx)?;
self.runtime
.block_on(self.node.submit_transaction(&authorized_transaction))?;
self.node.submit_transaction(authorized_transaction)?;
self.update_utxos()?;
Ok(())
}
Expand Down Expand Up @@ -157,6 +152,7 @@ impl App {
inbox_whitelist.contains(bitname)
})
};
let tip = self.node.get_tip()?;
let outpoints_to_block_heights: HashMap<_, _> = utxos
.iter()
.map(|(&outpoint, _)| outpoint)
Expand All @@ -166,8 +162,16 @@ impl App {
_ => None,
})
.map(|(outpoint, txid)| {
let height = self.node.get_tx_height(txid)?;
Ok((outpoint, height))
let inclusions = self.node.get_tx_inclusions(txid)?;
let Some(block_hash) =
inclusions.into_iter().try_find(|block_hash| {
self.node.is_descendant(*block_hash, tip)
})?
else {
return Ok((outpoint, None));
};
let height = self.node.get_height(block_hash)?;
Ok((outpoint, Some(height)))
})
.collect::<Result<_, node::Error>>()?;
let inpoints_to_block_heights: HashMap<_, _> =
Expand All @@ -179,8 +183,14 @@ impl App {
"Impossible: bitname inpoint can only refer to regular tx"
)
};
let height = self.node.get_tx_height(txid)?;
Ok((spent_output.inpoint, height))
let inclusions = self.node.get_tx_inclusions(txid)?;
let Some(block_hash) = inclusions.into_iter().try_find(|block_hash| {
self.node.is_descendant(*block_hash, tip)
})? else {
return Ok((spent_output.inpoint, None));
};
let height = self.node.get_height(block_hash)?;
Ok((spent_output.inpoint, Some(height)))
}).collect::<Result<_, node::Error>>()?;
/* associate to each address, a set of pairs of bitname data and
ownership period for the bitname. */
Expand All @@ -192,7 +202,9 @@ impl App {
continue;
};
let bitname_data = self.node.get_current_bitname_data(bitname)?;
let height = outpoints_to_block_heights[&outpoint];
let Some(height) = outpoints_to_block_heights[&outpoint] else {
continue;
};
let owned = Range {
start: height,
end: u32::MAX,
Expand All @@ -207,14 +219,17 @@ impl App {
let Some(bitname) = output.output.bitname() else {
continue;
};
let acquired_height = outpoints_to_block_heights[&outpoint];
let Some(acquired_height) = outpoints_to_block_heights[&outpoint]
else {
continue;
};
let spent_height = inpoints_to_block_heights[&output.inpoint];
let bitname_data = self
.node
.get_bitname_data_at_block_height(bitname, acquired_height)?;
let owned = Range {
start: acquired_height,
end: spent_height,
end: spent_height.unwrap_or(u32::MAX),
};
addrs_to_bitnames_ownership
.entry(output.output.address)
Expand All @@ -231,7 +246,9 @@ impl App {
else {
return false;
};
let height = outpoints_to_block_heights[outpoint];
let Some(height) = outpoints_to_block_heights[outpoint] else {
return false;
};
let min_fee = bitname_data_ownership
.iter()
.filter_map(|(bitname_data, ownership)| {
Expand Down Expand Up @@ -278,7 +295,7 @@ impl App {
let txs = txs.into_iter().map(|tx| tx.into()).collect();
Body::new(txs, coinbase)
};
let prev_side_hash = self.node.get_best_hash()?;
let prev_side_hash = self.node.get_tip()?;
let prev_main_hash = self
.miner
.read()
Expand Down
4 changes: 2 additions & 2 deletions app/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub struct Cli {
/// Path to a mnemonic seed phrase
#[arg(long)]
pub mnemonic_seed_phrase_path: Option<PathBuf>,
/// address to use for P2P networking, defaults to 127.0.0.1:4000
/// address to use for P2P networking, defaults to 0.0.0.0:4000
#[arg(short, long)]
pub net_addr: Option<String>,
/// mainchain node RPC password, defaults to "password"
Expand Down Expand Up @@ -73,7 +73,7 @@ impl Cli {
.clone()
.unwrap_or_else(|| "password".into());
let main_user = self.user_main.clone().unwrap_or_else(|| "user".into());
const DEFAULT_NET_ADDR: &str = "127.0.0.1:4000";
const DEFAULT_NET_ADDR: &str = "0.0.0.0:4000";
let net_addr: SocketAddr = self
.net_addr
.clone()
Expand Down
22 changes: 17 additions & 5 deletions app/gui/activity/block_explorer.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use eframe::egui;
use human_size::{Byte, Kibibyte, Mebibyte, SpecificSize};

use plain_bitnames::{bip300301::bitcoin, types::GetValue};
use plain_bitnames::{
bip300301::bitcoin,
types::{Body, GetValue, Header},
};

use crate::app::App;

Expand All @@ -15,9 +18,18 @@ impl BlockExplorer {
}

pub fn show(&mut self, app: &mut App, ui: &mut egui::Ui) {
let max_height = app.node.get_height().unwrap_or(0);
let header = app.node.get_header(self.height).ok().flatten();
let body = app.node.get_body(self.height).ok().flatten();
let max_height = app.node.get_tip_height().unwrap_or(0);
let block: Option<(Header, Body)> = {
if let Ok(Some(block_hash)) =
app.node.try_get_block_hash(self.height)
&& let Ok(header) = app.node.get_header(block_hash)
&& let Ok(body) = app.node.get_body(block_hash)
{
Some((header, body))
} else {
None
}
};
egui::CentralPanel::default().show_inside(ui, |ui| {
ui.heading("Block");
ui.horizontal(|ui| {
Expand All @@ -32,7 +44,7 @@ impl BlockExplorer {
self.height = max_height;
}
});
if let (Some(header), Some(body)) = (header, body) {
if let Some((header, body)) = block {
let hash = &format!("{}", header.hash());
let merkle_root = &format!("{}", header.merkle_root);
let prev_side_hash = &format!("{}", header.prev_side_hash);
Expand Down
2 changes: 1 addition & 1 deletion app/gui/activity/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub struct Activity {

impl Activity {
pub fn new(app: &App) -> Self {
let height = app.node.get_height().unwrap_or(0);
let height = app.node.get_tip_height().unwrap_or(0);
Self {
tab: Default::default(),
block_explorer: BlockExplorer::new(height),
Expand Down
8 changes: 4 additions & 4 deletions app/gui/miner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ impl Default for Miner {

impl Miner {
pub fn show(&mut self, app: &App, ui: &mut egui::Ui) {
let block_height = app.node.get_height().unwrap_or(0);
let best_hash = app.node.get_best_hash().unwrap_or([0; 32].into());
let block_height = app.node.get_tip_height().unwrap_or(0);
let best_hash = app.node.get_tip().unwrap_or([0; 32].into());
ui.label("Block height: ");
ui.monospace(format!("{block_height}"));
ui.label("Best hash: ");
Expand All @@ -36,10 +36,10 @@ impl Miner {
.clicked()
{
self.running.store(true, atomic::Ordering::SeqCst);
app.runtime.spawn({
app.local_pool.spawn_pinned({
let app = app.clone();
let running = self.running.clone();
async move {
|| async move {
tracing::debug!("Mining...");
let mining_result = app.mine(None).await;
running.store(false, atomic::Ordering::SeqCst);
Expand Down
3 changes: 3 additions & 0 deletions app/main.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
#![feature(let_chains)]
#![feature(try_find)]

use std::sync::mpsc;

use clap::Parser as _;
Expand Down
24 changes: 6 additions & 18 deletions app/rpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,7 @@ impl RpcServer for RpcServerImpl {
}

async fn connect_peer(&self, addr: SocketAddr) -> RpcResult<()> {
self.app
.node
.connect_peer(addr)
.await
.map_err(convert_node_err)
self.app.node.connect_peer(addr).map_err(convert_node_err)
}

async fn format_deposit_address(
Expand Down Expand Up @@ -87,17 +83,6 @@ impl RpcServer for RpcServerImpl {
Ok(block)
}

async fn get_block_hash(&self, height: u32) -> RpcResult<BlockHash> {
let block_hash = self
.app
.node
.get_header(height)
.map_err(convert_node_err)?
.ok_or_else(|| custom_err("block not found"))?
.hash();
Ok(block_hash)
}

async fn get_new_address(&self) -> RpcResult<Address> {
self.app
.wallet
Expand All @@ -110,12 +95,15 @@ impl RpcServer for RpcServerImpl {
}

async fn getblockcount(&self) -> RpcResult<u32> {
self.app.node.get_height().map_err(convert_node_err)
self.app.node.get_tip_height().map_err(convert_node_err)
}

async fn mine(&self, fee: Option<u64>) -> RpcResult<()> {
let fee = fee.map(bip300301::bitcoin::Amount::from_sat);
self.app.mine(fee).await.map_err(convert_app_err)
self.app.local_pool.spawn_pinned({
let app = self.app.clone();
move || async move { app.mine(fee).await.map_err(convert_app_err) }
}).await.unwrap()
}

async fn my_utxos(&self) -> RpcResult<Vec<FilledOutput>> {
Expand Down
6 changes: 0 additions & 6 deletions cli/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,6 @@ pub enum Command {
GetNewAddress,
/// Get the current block count
GetBlockcount,
/// Get the hash of the block at the specified height
GetBlockHash { height: u32 },
/// Get all paymail
GetPaymail,
/// Attempt to mine a sidechain block
Expand Down Expand Up @@ -103,10 +101,6 @@ impl Cli {
let block = rpc_client.get_block(block_hash).await?;
serde_json::to_string_pretty(&block)?
}
Command::GetBlockHash { height } => {
let block_hash = rpc_client.get_block_hash(height).await?;
format!("{block_hash}")
}
Command::GetBlockcount => {
let blockcount = rpc_client.getblockcount().await?;
format!("{blockcount}")
Expand Down
Loading

0 comments on commit ded1293

Please sign in to comment.