diff --git a/Cargo.toml b/Cargo.toml index 5fa2d2c..20af316 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -34,7 +34,7 @@ lightning-net-tokio = { git = "https://github.com/civkit/rust-lightning.git", br lightning-invoice = { git = "https://github.com/civkit/rust-lightning.git", branch = "civkit-branch" } tokio = { version = "1", features = [ "io-util", "macros", "rt", "rt-multi-thread", "sync", "net", "time" ] } tokio-tungstenite = "0.19.0" -bitcoin = { version = "0.29.0", features = ["rand"] } +bitcoin = { version = "0.29.0", features = ["rand", "serde"] } bitcoin_hashes = { version = "0.11", default-features = false } tonic = "0.9" prost = "0.11" diff --git a/check_config.sh b/check_config.sh index f21ea47..6f2dca8 100644 --- a/check_config.sh +++ b/check_config.sh @@ -1,11 +1,14 @@ #!/bin/bash +# might be outdated as we generate a default config.toml on first start + # Define the path to the config file -CONFIG_FILE="./example-config.toml" +CONFIG_FILE="./config.toml" +# TODO does not match Config::default() # Check if the file exists if [[ ! -f $CONFIG_FILE ]]; then - echo "example-config.toml not found. Creating a default one..." + echo "config.toml not found. Creating a default one..." # Define the default content for the config file config_content='[performance] @@ -30,5 +33,5 @@ level = "info"' # Write the default content to the config file echo "$config_content" > $CONFIG_FILE else - echo "example-config.toml already exists." + echo "config.toml already exists." fi diff --git a/example-config.toml b/example-config.toml index 16c9084..4d89cea 100644 --- a/example-config.toml +++ b/example-config.toml @@ -16,3 +16,18 @@ cli_port = 50031 [logging] level = "info" + +[mainstay] +url = "https://mainstay.xyz/api/v1" +position = 1 +token = "14b2b754-5806-4157-883c-732baf88849c" +base_pubkey = "031dd94c5262454986a2f0a6c557d2cbe41ec5a8131c588b9367c9310125a8a7dc" +chain_code = "0a090f710e47968aee906804f211cf10cde9a11e14908ca0f78cc55dd190ceaa" + +[bitcoind_params] +host = "https://127.0.0.1" +port = "18443" +rpc_user = "civkitd_client" +rpc_password = "hello_world" +# can be "bitcoin" or "testnet" +chain = "testnet" diff --git a/src/clienthandler.rs b/src/clienthandler.rs index b22e677..b6f78cb 100644 --- a/src/clienthandler.rs +++ b/src/clienthandler.rs @@ -99,9 +99,9 @@ async fn handle_connection(raw_stream: TcpStream, addr: SocketAddr, outgoing_rec Ok(Message::Text(msg)) => { outgoing_receive.send(msg.into()); }, Ok(Message::Binary(msg)) => { outgoing_receive.send(msg); }, Ok(Message::Close(None)) => { break; }, - _ => { + other => { //TODO: if failure client state cleanly - panic!("[CIVKITD] - NOSTR: unknown webSocket message ?!"); + println!("[CIVKITD] unknow message: {:?}", Some(other)); }, } } @@ -170,7 +170,7 @@ impl ClientHandler { { // We receive an offer processed by the relay management utility, or any other // service-side Nostr event. - let mut handler_receive_lock = self.handler_receive.lock(); + let handler_receive_lock = self.handler_receive.lock(); if let Ok(event) = handler_receive_lock.await.try_recv() { println!("[CIVKITD] - PROCESSING: received an event from service manager"); diff --git a/src/config.rs b/src/config.rs index f83499c..a8660af 100644 --- a/src/config.rs +++ b/src/config.rs @@ -1,8 +1,11 @@ use std::fs; +use bitcoin::{Block, BlockHeader, Network}; +use serde::Serializer; use toml; -use serde_derive::Deserialize; +use serde_derive::{Deserialize, Serialize}; -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] + +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct Config { pub performance: Performance, pub spam_protection: SpamProtection, @@ -13,23 +16,23 @@ pub struct Config { pub bitcoind_params: BitcoindParams, } -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct Performance { pub max_db_size: i32, pub max_event_age: i32, } -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct SpamProtection { pub requestcredentials: bool, } -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct Connections { pub maxclientconnections: i32, } -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct Civkitd { pub network: String, pub noise_port: i32, @@ -37,12 +40,12 @@ pub struct Civkitd { pub cli_port: i32, } -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct Logging { pub level: String, } -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct Mainstay { pub url: String, pub position: i32, @@ -51,12 +54,13 @@ pub struct Mainstay { pub chain_code: String, } -#[derive(Clone, PartialEq, Eq, Debug, Deserialize)] +#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)] pub struct BitcoindParams { pub host: String, pub port: String, pub rpc_user: String, pub rpc_password: String, + pub chain: bitcoin::Network, } // default config to fallback @@ -94,6 +98,7 @@ impl Default for Config { port: "18443".to_string(), // regtest rpc_user: "civkitd_client".to_string(), rpc_password: "hello_world".to_string(), + chain: bitcoin::Network::Testnet, } } } diff --git a/src/sample.rs b/src/sample.rs index 761ce4a..71a1964 100644 --- a/src/sample.rs +++ b/src/sample.rs @@ -483,7 +483,7 @@ async fn respond( } _ => { println!("Unknown command"); - return Ok(true); + return Ok(false); } } @@ -493,10 +493,10 @@ async fn respond( async fn poll_for_server_output(mut rx: futures_channel::mpsc::UnboundedReceiver) { loop { - if let Ok(message) = rx.try_next() { + if let message = rx.next().await { let msg = message.unwrap(); let msg_json = String::from_utf8(msg.into()).unwrap(); - //println!("Received message {}", msg_json); + println!("Received message {}", msg_json); if let Ok(relay_msg) = RelayMessage::from_json(msg_json) { match relay_msg { RelayMessage::Event { subscription_id, event } => { @@ -555,7 +555,7 @@ async fn poll_for_server_output(mut rx: futures_channel::mpsc::UnboundedReceiver #[tokio::main] async fn main() -> Result<(), Box> { - + // TODO add documentation for this option and use it let connect_addr = env::args().nth(1).unwrap_or_else(|| "50021".to_string()); let addr = format!("ws://[::1]:50021"); diff --git a/src/server.rs b/src/server.rs index 2862e7c..1a2661a 100644 --- a/src/server.rs +++ b/src/server.rs @@ -15,7 +15,7 @@ mod util; use bitcoin::MerkleBlock; -use crate::util::init_logger; +use crate::util::{init_logger, get_default_data_dir}; use log; use std::fs; use crate::servicemanager::ServiceManager; @@ -361,25 +361,25 @@ struct Cli { #[clap(short, long, default_value = "50031")] cli_port: String, } - -fn main() -> Result<(), Box> { +#[tokio::main] +async fn main() { let data_dir = util::get_default_data_dir(); - - let config_path = data_dir.join("example-config.toml"); - + fs::create_dir_all(get_default_data_dir()).unwrap(); + let config_path = data_dir.join("config.toml"); + // Check if the config file exists + if !config_path.exists() { + // Create a file with the default configuration + let default_config = Config::default(); + let toml_string = toml::to_string(&default_config).expect("Failed to serialize default config"); + + fs::write(&config_path, toml_string).expect("Failed to write default config file"); + println!("Created default config file at {:?}", config_path); + } // Read the configuration file - let contents = fs::read_to_string(&config_path); - let config = match contents { - Ok(data) => { - toml::from_str(&data).expect("Could not deserialize the config file content") - }, - Err(_) => { - // If there's an error reading the file, use the default configuration - Config::default() - } - }; + let contents = fs::read_to_string(&config_path).expect("could not read config file"); + let config : Config = toml::from_str(&contents).expect("Could not deserialize the config file content"); // Initialize the logger with the level from the config - util::init_logger(&data_dir, &config.logging.level)?; + util::init_logger(&data_dir, &config.logging.level).unwrap(); log::info!("Logging initialized. Log file located at: {:?}", data_dir.join("debug.log")); @@ -398,7 +398,6 @@ fn main() -> Result<(), Box> { println!("[CIVKITD] - INIT: noise port {} nostr port {} cli_port {}", cli.noise_port, cli.nostr_port, cli.cli_port); - let rt = Runtime::new()?; // We initialize the communication channels between the service manager and ClientHandler. let (service_mngr_events_send, handler_receive) = mpsc::unbounded_channel::(); @@ -461,7 +460,7 @@ fn main() -> Result<(), Box> { // Main handler of services provision. let service_manager_arc = Arc::new(ServiceManager::new(node_signer, anchor_manager, service_mngr_events_send, service_mngr_peer_send, manager_send_dbrequests, manager_send_bitcoind_request, send_events_gateway, Arc::new(inclusion_proof.clone()), config.clone())); - let addr = format!("[::1]:{}", cli.cli_port).parse()?; + let addr = format!("[::1]:{}", cli.cli_port).parse().expect("Failed to parse address, port might be invalid?"); let service_mngr_svc = Server::builder() .add_service(AdminCtrlServer::new(service_manager_arc.clone())) @@ -472,8 +471,6 @@ fn main() -> Result<(), Box> { let stop_listen_connect = Arc::new(AtomicBool::new(false)); let stop_listen = Arc::clone(&stop_listen_connect); - rt.block_on(async { - // We start the gRPC server for `civkit-cli`. tokio::spawn(async move { if let Err(e) = service_mngr_svc.await { @@ -537,7 +534,7 @@ fn main() -> Result<(), Box> { }); // We start the tcp listener for NIP-01 clients. - tokio::spawn(async move { + let handle = tokio::spawn(async move { let try_socket = TcpListener::bind(format!("[::1]:{}", cli.nostr_port)).await; let listener = try_socket.expect("Failed to bind"); @@ -549,10 +546,7 @@ fn main() -> Result<(), Box> { }); - loop {} - - }); + handle.await; //TEMPORARY SOLUTION should use ALL handles or block indefinetely TODO - Ok(()) } diff --git a/src/servicemanager.rs b/src/servicemanager.rs index cf5af18..a370210 100644 --- a/src/servicemanager.rs +++ b/src/servicemanager.rs @@ -64,7 +64,7 @@ impl ServiceManager let secp_ctx = Secp256k1::new(); let pubkey = PublicKey::from_secret_key(&secp_ctx, &SecretKey::from_slice(&[42;32]).unwrap()); ServiceManager { - genesis_hash: genesis_block(Network::Testnet).header.block_hash(), + genesis_hash: genesis_block(our_config.bitcoind_params.chain).header.block_hash(), anchor_manager, node_signer, service_events_send: Mutex::new(board_events_send), diff --git a/src/util.rs b/src/util.rs index 9c77672..38f9f97 100644 --- a/src/util.rs +++ b/src/util.rs @@ -18,7 +18,7 @@ pub fn get_default_data_dir() -> PathBuf { // Determine the platform-specific path let platform_path = if cfg!(target_os = "linux") { // Path for Linux (Debian/Ubuntu) - home_dir.join("./civkit-node") + home_dir.join("./.civkit-node") } else if cfg!(target_os = "macos") { // Path for MacOS home_dir.join("Library/Application Support/civkit-node")