Skip to content

Commit

Permalink
Merge pull request #4 from torkelrogstad/2024-09-27-config
Browse files Browse the repository at this point in the history
config: add RPC user+password, rework cookie auth
  • Loading branch information
Ash-L2L authored Oct 1, 2024
2 parents ec6e4d2 + 57b0f24 commit 1a0707a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 43 deletions.
73 changes: 42 additions & 31 deletions src/bip300.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
use std::collections::{HashMap, HashSet};
use std::net::SocketAddr;
use std::path::PathBuf;
use std::{io::Cursor, path::Path, str::FromStr, time::Duration};

use bip300301_messages::bitcoin::hashes::Hash;
Expand All @@ -22,6 +20,7 @@ use tokio::time::{interval, Instant};
use tokio_stream::wrappers::IntervalStream;
use ureq_jsonrpc::{json, Client};

use crate::cli::Config;
use crate::types::{
Ctip, Deposit, Hash256, PendingM6id, Sidechain, SidechainProposal, TreasuryUtxo,
};
Expand Down Expand Up @@ -761,8 +760,8 @@ impl Bip300 {
Ok(())
}

async fn task(&self, main_datadir: PathBuf, main_address: SocketAddr) -> Result<()> {
let main_client = &create_client(main_datadir, main_address)?;
async fn task(&self, conf: Config) -> Result<()> {
let main_client = &create_client(conf)?;
let () = self.initial_sync(main_client)?;
let interval = interval(Duration::from_secs(1));
IntervalStream::new(interval)
Expand All @@ -771,12 +770,10 @@ impl Bip300 {
.await
}

pub fn run(&self, main_datadir: &Path, main_address: SocketAddr) -> JoinHandle<()> {
let main_datadir = main_datadir.to_owned();
let main_address = main_address.to_owned();
pub fn run(&self, conf: Config) -> JoinHandle<()> {
let this = self.clone();
tokio::task::spawn(async move {
this.task(main_datadir, main_address)
this.task(conf)
.unwrap_or_else(|err| eprintln!("{err:#}"))
.await
})
Expand Down Expand Up @@ -893,30 +890,44 @@ impl Bip300 {
*/
}

fn create_client(main_datadir: PathBuf, main_address: SocketAddr) -> Result<Client> {
let cookie_path = main_datadir.join("regtest/.cookie");
let auth = std::fs::read_to_string(cookie_path.clone()).map_err(|err| {
miette!(
"unable to read bitcoind cookie at {}: {}",
cookie_path.display(),
err
)
})?;

let mut auth = auth.split(':');
let user = auth
.next()
.ok_or(miette!("failed to get rpcuser"))?
.to_string();
let password = auth
.next()
.ok_or(miette!("failed to get rpcpassword"))?
.to_string();
fn create_client(conf: Config) -> Result<Client> {
if conf.node_rpc_user.is_none() != conf.node_rpc_password.is_none() {
return Err(miette!("RPC user and password must be set together"));
}

if conf.node_rpc_user.is_none() == conf.node_rpc_cookie_path.is_none() {
return Err(miette!("precisely one of RPC user and cookie must be set"));
}

let mut conf_user = conf.node_rpc_user.clone().unwrap_or_default();
let mut conf_password = conf.node_rpc_password.clone().unwrap_or_default();

if conf.node_rpc_cookie_path.is_some() {
let cookie_path = conf.node_rpc_cookie_path.clone().unwrap();
let auth = std::fs::read_to_string(cookie_path.clone())
.map_err(|err| miette!("unable to read bitcoind cookie at {}: {}", cookie_path, err))?;

let mut auth = auth.split(':');

conf_user = auth
.next()
.ok_or(miette!("failed to get rpcuser"))?
.to_string()
.clone();

conf_password = auth
.next()
.ok_or(miette!("failed to get rpcpassword"))?
.to_string()
.to_string()
.clone();
}

Ok(Client {
host: main_address.ip().to_string(),
port: 18443,
user,
password,
host: conf.node_rpc_host.to_string(),
port: conf.node_rpc_port,
user: conf_user.to_string(),
password: conf_password.to_string(),
id: "mainchain".into(),
})
}
29 changes: 20 additions & 9 deletions src/cli.rs
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
use std::{
net::{Ipv4Addr, SocketAddr, SocketAddrV4},
path::PathBuf,
};
use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};

use clap::Parser;

#[derive(Parser)]
pub struct Cli {
#[arg(default_value_t = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 18_443)), long)]
pub node_rpc_addr: SocketAddr,
pub struct Config {
#[arg(default_value = "localhost", long)]
pub node_rpc_host: String,

#[arg(default_value = "../data/bitcoin", long)]
pub node_rpc_datadir: PathBuf,
#[arg(default_value = "18443", long)]
pub node_rpc_port: u16,

/// Path to Bitcoin Core cookie. Cannot be set together with user + password.
#[arg(long)]
pub node_rpc_cookie_path: Option<String>,

/// RPC user for Bitcoin Core. Implies also setting password.
/// Cannot be set together with cookie path.
#[arg(long)]
pub node_rpc_user: Option<String>,

/// RPC password for Bitcoin Core. Implies also setting user. Cannot
/// be set together with cookie path.
#[arg(long)]
pub node_rpc_password: Option<String>,

#[arg(default_value_t = SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::LOCALHOST, 50_051)), long)]
pub serve_rpc_addr: SocketAddr,
Expand Down
7 changes: 4 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,19 @@ async fn run_server(bip300: Bip300, addr: SocketAddr) -> Result<()> {

#[tokio::main]
async fn main() -> Result<()> {
let cli = cli::Cli::parse();
let cli = cli::Config::parse();
let serve_rpc_addr = cli.serve_rpc_addr;

let bip300 = Bip300::new(Path::new("./"))?;

let task = bip300
.run(&cli.node_rpc_datadir, cli.node_rpc_addr)
.run(cli)
.map(|res| res.into_diagnostic())
.map_err(|err| miette!("unable to initialize bip300 handler: {}", err))
.unwrap_or_else(|err| eprintln!("{err:#}"));

//let ((), ()) = future::try_join(task.map(Ok), run_server(bip300, addr)).await?;
match future::select(task, run_server(bip300, cli.serve_rpc_addr).boxed()).await {
match future::select(task, run_server(bip300, serve_rpc_addr).boxed()).await {
Either::Left(((), server_task)) => {
// continue to run server task
server_task.await
Expand Down

0 comments on commit 1a0707a

Please sign in to comment.