Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CHANGELOG.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@

== DFX

=== feat: Allow users to configure logging level of bitcoin adapter

The bitcoin adapter's logging can be very verbose if debug logging is enabled, making it difficult to make sense of what's going on. On the other hand, these logs are useful for triaging problems.

To get the best of both worlds, this commit adds support for an additional configuration option in dfx.json:
Comment thread
ielashi marked this conversation as resolved.
Outdated

"bitcoin": {
"enabled": true,
"nodes": ["127.0.0.1:18444"],
"log_level": "info" <------- users can now configure the log level
}

By default, a log level of "info" is used, which is relatively quiet. Users can change it to "debug" for more verbose logging.

=== chore: update Candid UI canister with commit bffa0ae3c416e8aa3c92c33722a6b1cb31d0f1c3

This includes the following changes:
Expand Down
6 changes: 4 additions & 2 deletions src/dfx/src/commands/start.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ pub fn configure_btc_adapter_if_enabled(
nodes: Vec<SocketAddr>,
) -> DfxResult<Option<bitcoin::adapter::Config>> {
let enable = enable_bitcoin || !nodes.is_empty() || config.get_defaults().get_bitcoin().enabled;
let log_level = config.get_defaults().get_bitcoin().log_level;

if !enable {
return Ok(None);
Expand All @@ -446,7 +447,7 @@ pub fn configure_btc_adapter_if_enabled(
(_, _) => bitcoin::adapter::config::default_nodes(),
};

let config = write_btc_adapter_config(uds_holder_path, config_path, nodes)?;
let config = write_btc_adapter_config(uds_holder_path, config_path, nodes, log_level)?;
Ok(Some(config))
}

Expand Down Expand Up @@ -486,10 +487,11 @@ fn write_btc_adapter_config(
uds_holder_path: &Path,
config_path: &Path,
nodes: Vec<SocketAddr>,
log_level: bitcoin::adapter::config::Level,
) -> DfxResult<bitcoin::adapter::Config> {
let socket_path = get_persistent_socket_path(uds_holder_path, "ic-btc-adapter-socket")?;

let adapter_config = bitcoin::adapter::Config::new(nodes, socket_path);
let adapter_config = bitcoin::adapter::Config::new(nodes, socket_path, log_level);

let contents = serde_json::to_string_pretty(&adapter_config)
.context("Unable to serialize btc adapter configuration to json")?;
Expand Down
88 changes: 87 additions & 1 deletion src/dfx/src/config/dfinity.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(dead_code)]
use crate::lib::bitcoin::adapter::config::Level;
use crate::lib::error::{BuildError, DfxError, DfxResult};
use crate::util::SerdeVec;
use crate::{error_invalid_argument, error_invalid_config, error_invalid_data};
Expand Down Expand Up @@ -26,6 +27,7 @@ const EMPTY_CONFIG_DEFAULTS: ConfigDefaults = ConfigDefaults {
const EMPTY_CONFIG_DEFAULTS_BITCOIN: ConfigDefaultsBitcoin = ConfigDefaultsBitcoin {
enabled: false,
nodes: None,
log_level: Level::Info,
Comment thread
viviveevee marked this conversation as resolved.
Outdated
};

const EMPTY_CONFIG_DEFAULTS_CANISTER_HTTP: ConfigDefaultsCanisterHttp =
Expand Down Expand Up @@ -95,14 +97,18 @@ pub struct CanisterDeclarationsConfig {
pub env_override: Option<String>,
}

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
#[derive(Clone, Debug, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct ConfigDefaultsBitcoin {
#[serde(default = "default_as_false")]
pub enabled: bool,

/// Addresses of nodes to connect to (in case discovery from seeds is not possible/sufficient)
#[serde(default)]
pub nodes: Option<Vec<SocketAddr>>,

/// The logging level of the adapter (e.g. "info", "debug", "error", etc.)
#[serde(default)]
pub log_level: Level,
}

#[derive(Clone, Debug, Default, Serialize, Deserialize)]
Expand Down Expand Up @@ -580,6 +586,7 @@ impl Config {
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;

#[test]
fn find_dfinity_config_current_path() {
Expand Down Expand Up @@ -774,4 +781,83 @@ mod tests {
assert_eq!(None, compute_allocation);
assert_eq!(None, memory_allocation);
}

#[test]
fn get_bitcoin_config() {
let config = Config::from_str(
r#"{
"defaults": {
"bitcoin": {
"enabled": true,
"nodes": ["127.0.0.1:18444"],
"log_level": "info"
}
}
}"#,
)
.unwrap();

let bitcoin_config = config.get_config().get_defaults().get_bitcoin();

assert_eq!(
bitcoin_config,
&ConfigDefaultsBitcoin {
enabled: true,
nodes: Some(vec![SocketAddr::from_str("127.0.0.1:18444").unwrap()]),
log_level: Level::Info
}
);
}

#[test]
fn get_bitcoin_config_default_log_level() {
let config = Config::from_str(
r#"{
"defaults": {
"bitcoin": {
"enabled": true,
"nodes": ["127.0.0.1:18444"]
}
}
}"#,
)
.unwrap();

let bitcoin_config = config.get_config().get_defaults().get_bitcoin();

assert_eq!(
bitcoin_config,
&ConfigDefaultsBitcoin {
enabled: true,
nodes: Some(vec![SocketAddr::from_str("127.0.0.1:18444").unwrap()]),
log_level: Level::Info // A default log level of "info" is assumed
}
);
}

#[test]
fn get_bitcoin_config_debug_log_level() {
let config = Config::from_str(
r#"{
"defaults": {
"bitcoin": {
"enabled": true,
"log_level": "debug"
}
}
}"#,
)
.unwrap();

let bitcoin_config = config.get_config().get_defaults().get_bitcoin();

assert_eq!(
bitcoin_config,
&ConfigDefaultsBitcoin {
enabled: true,
nodes: None,
log_level: Level::Debug
}
);
}
}
45 changes: 44 additions & 1 deletion src/dfx/src/lib/bitcoin/adapter/config.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use serde::{Deserialize, Serialize};
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::path::PathBuf;
use std::str::FromStr;

const BITCOIND_REGTEST_DEFAULT_PORT: u16 = 18444;

Expand Down Expand Up @@ -35,6 +36,45 @@ impl Default for IncomingSource {
}
}

/// Represents the log level.
#[derive(Clone, Debug, Serialize, Deserialize, Copy, PartialEq, Eq)]
#[serde(rename_all = "snake_case")]
pub enum Level {
Comment thread
viviveevee marked this conversation as resolved.
Outdated
Critical,
Error,
Warning,
Info,
Debug,
Trace,
}

impl FromStr for Level {
type Err = String;

fn from_str(input: &str) -> Result<Level, Self::Err> {
match input {
"critical" => Ok(Level::Critical),
"error" => Ok(Level::Error),
"warning" => Ok(Level::Warning),
"info" => Ok(Level::Info),
"debug" => Ok(Level::Debug),
"trace" => Ok(Level::Trace),
other => Err(format!("Unknown log level: {}", other)),
}
}
}

impl Default for Level {
fn default() -> Self {
Level::Info
}
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct LoggerConfig {
level: Level,
}

/// This struct contains configuration options for the BTC Adapter.
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Config {
Expand All @@ -50,15 +90,18 @@ pub struct Config {
/// Specifies which unix domain socket should be used for serving incoming requests.
#[serde(default)]
pub incoming_source: IncomingSource,

pub logger: LoggerConfig,
}

impl Config {
pub fn new(nodes: Vec<SocketAddr>, uds_path: PathBuf) -> Config {
pub fn new(nodes: Vec<SocketAddr>, uds_path: PathBuf, log_level: Level) -> Config {
Config {
network: String::from("regtest"),
nodes,
idle_seconds: Some(FORCED_IDLE_SECONDS),
incoming_source: IncomingSource::Path(uds_path),
logger: LoggerConfig { level: log_level },
}
}

Expand Down