diff --git a/crates/bin/pmonitor/src/config.rs b/crates/bin/pmonitor/src/config.rs index 7f734e8541..8b521ff8a1 100644 --- a/crates/bin/pmonitor/src/config.rs +++ b/crates/bin/pmonitor/src/config.rs @@ -1,3 +1,4 @@ +//! Logic for reading and writing config files for `pmonitor`, in the TOML format. use anyhow::Result; use regex::Regex; use serde::{Deserialize, Serialize}; @@ -8,18 +9,21 @@ use penumbra_keys::FullViewingKey; use penumbra_num::Amount; #[derive(Clone, Debug, Serialize, Deserialize)] - pub struct FvkEntry { pub fvk: FullViewingKey, pub wallet_id: Uuid, } #[derive(Clone, Debug, Serialize, Deserialize)] - +/// Representation of a single Penumbra wallet to track. pub struct AccountConfig { + /// The initial [FullViewingKey] has specified during `pmonitor init`. + /// + /// Distinct because the tool understands account migrations. original: FvkEntry, + /// The amount held by the account at the time of genesis. genesis_balance: Amount, - // If the account was migrated, we update the entry here. + /// List of account migrations, performed via `pcli migrate balance`, if any. migrations: Vec, } @@ -69,8 +73,15 @@ impl AccountConfig { } #[derive(Clone, Debug, Serialize, Deserialize)] +/// The primary TOML file for configuring `pmonitor`, containing all its account info. +/// +/// During `pmonitor audit` runs, the config will be automatically updated +/// if tracked FVKs were detected to migrate, via `pcli migrate balance`, to save time +/// on future syncs. pub struct PmonitorConfig { + /// The gRPC URL for a Penumbra node's `pd` endpoint, used for retrieving account activity. grpc_url: Url, + /// The list of Penumbra wallets to track. accounts: Vec, } diff --git a/crates/bin/pmonitor/src/genesis.rs b/crates/bin/pmonitor/src/genesis.rs index efcb800c2c..a526e2899d 100644 --- a/crates/bin/pmonitor/src/genesis.rs +++ b/crates/bin/pmonitor/src/genesis.rs @@ -1,3 +1,6 @@ +//! Logic for inspecting the [CompactBlock] at genesis of the target chain. +//! Used to compute balances for tracked FVKs at genesis time. The initial genesis balance is +//! stored in the `pmonitor` config file, so that audit actions can reference it. use std::{collections::BTreeMap, str::FromStr}; use penumbra_asset::STAKING_TOKEN_ASSET_ID; diff --git a/crates/bin/pmonitor/src/main.rs b/crates/bin/pmonitor/src/main.rs index 9a81cf4345..6549254b10 100644 --- a/crates/bin/pmonitor/src/main.rs +++ b/crates/bin/pmonitor/src/main.rs @@ -1,3 +1,19 @@ +//! The `pmonitor` tool tracks the balances of Penumbra wallets, as identified +//! by a [FullViewingKey] (FVK), in order to perform auditing. It accepts a JSON file +//! of FVKs and a `pd` gRPC URL to initialize: +//! +//! pmonitor init --grpc-url http://127.0.0.1:8080 --fvks fvks.json +//! +//! The audit functionality runs as a single operation, evaluating compliance up to the +//! current block height: +//! +//! pmonitor audit +//! +//! If regular auditing is desired, consider automating the `pmonitor audit` action via +//! cron or similar. `pmonitor` will cache view databases for each tracked FVK, so that future +//! `audit` actions need only inspect the blocks generated between the previous audit and the +//! current height. + use anyhow::{Context, Result}; use camino::Utf8PathBuf; use clap::{self, Parser}; @@ -36,14 +52,14 @@ mod genesis; use config::{parse_dest_fvk_from_memo, AccountConfig, FvkEntry, PmonitorConfig}; -// The maximum size of a compact block, in bytes (12MB). +/// The maximum size of a compact block, in bytes (12MB). const MAX_CB_SIZE_BYTES: usize = 12 * 1024 * 1024; -// The name of the view database file +/// The name of the view database file const VIEW_FILE_NAME: &str = "pcli-view.sqlite"; -// The permitted difference between genesis balance and current balance, -// specified in number of staking tokens. +/// The permitted difference between genesis balance and current balance, +/// specified in number of staking tokens. const ALLOWED_DISCREPANCY: f64 = 0.1; /// Configure tracing_subscriber for logging messages @@ -74,6 +90,9 @@ async fn main() -> Result<()> { opt.exec().await } +/// The path to the default `pmonitor` home directory. +/// +/// Can be overridden on the command-line via `--home`. pub fn default_home() -> Utf8PathBuf { let path = ProjectDirs::from("zone", "penumbra", "pmonitor") .expect("Failed to get platform data dir")