Skip to content

Commit 64820fd

Browse files
authored
fix: master_wallet can't be deleted or duplicated (#74)
Reserve the logical wallet name `master_wallet` in `nodectl`: operators cannot add a regular wallet with that name, and `config wallet rm` fails immediately with a clear error when that name is used.
1 parent ea8c013 commit 64820fd

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

src/node-control/commands/src/commands/nodectl/config_wallet_cmd.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
use crate::commands::nodectl::{
1010
output_format::OutputFormat,
1111
utils::{
12-
SEND_TIMEOUT, check_ton_api_connection, get_wallet_config, load_config_vault,
13-
load_config_vault_rpc_client, make_wallet, save_config, wait_for_seqno_change,
14-
wallet_address, wallet_info, warn_missing_secret, warn_ton_api_unavailable,
12+
MASTER_WALLET_RESERVED_NAME, SEND_TIMEOUT, check_ton_api_connection, get_wallet_config,
13+
load_config_vault, load_config_vault_rpc_client, make_wallet, save_config,
14+
wait_for_seqno_change, wallet_address, wallet_info, warn_missing_secret,
15+
warn_ton_api_unavailable,
1516
},
1617
};
1718
use anyhow::Context;
@@ -138,7 +139,7 @@ impl WalletCmd {
138139

139140
impl WalletAddCmd {
140141
pub async fn run(&self, path: &Path) -> anyhow::Result<()> {
141-
if self.name == "master_wallet" {
142+
if self.name == MASTER_WALLET_RESERVED_NAME {
142143
anyhow::bail!("'master_wallet' is a reserved name");
143144
}
144145

@@ -196,7 +197,7 @@ impl WalletLsCmd {
196197
let mut all_wallets: Vec<(&str, &WalletConfig)> =
197198
config.wallets.iter().map(|(k, v)| (k.as_str(), v)).collect();
198199
if let Some(mw) = config.master_wallet.as_ref() {
199-
all_wallets.push(("master_wallet", mw));
200+
all_wallets.push((MASTER_WALLET_RESERVED_NAME, mw));
200201
}
201202

202203
if all_wallets.is_empty() {
@@ -326,6 +327,10 @@ async fn print_wallets_table(
326327

327328
impl WalletRmCmd {
328329
pub async fn run(&self, path: &Path) -> anyhow::Result<()> {
330+
if self.name == MASTER_WALLET_RESERVED_NAME {
331+
anyhow::bail!("The master wallet cannot be removed");
332+
}
333+
329334
let mut config = AppConfig::load(path)?;
330335

331336
if !config.wallets.contains_key(&self.name) {

src/node-control/commands/src/commands/nodectl/utils.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ const POLL_INTERVAL: tokio::time::Duration = tokio::time::Duration::from_secs(2)
2929
pub const SEND_TIMEOUT: tokio::time::Duration = tokio::time::Duration::from_secs(15);
3030
pub const DEPLOY_TIMEOUT: tokio::time::Duration = tokio::time::Duration::from_secs(60);
3131

32+
/// Logical name for the master wallet in CLI, `get_wallet_config`, and `config wallet ls`.
33+
pub const MASTER_WALLET_RESERVED_NAME: &str = "master_wallet";
34+
3235
pub fn warn_missing_secret(secret_name: &str) {
3336
println!("\n{} {}", "[WARNING]".yellow().bold(), "Vault secret is missing".yellow(),);
3437
println!(
@@ -136,7 +139,8 @@ pub fn get_wallet_config<'a>(
136139
wallets: &'a HashMap<String, WalletConfig>,
137140
master_wallet: Option<&'a WalletConfig>,
138141
) -> anyhow::Result<&'a WalletConfig> {
139-
let config = if name == "master_wallet" { master_wallet } else { wallets.get(name) };
142+
let config =
143+
if name == MASTER_WALLET_RESERVED_NAME { master_wallet } else { wallets.get(name) };
140144
config.ok_or_else(|| anyhow::anyhow!("Wallet not found '{}'", name))
141145
}
142146

0 commit comments

Comments
 (0)