From ae1ddc9f1d442aea6b766467fdae1a4c29c9b2cc Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Wed, 27 Dec 2023 20:17:57 +0000 Subject: [PATCH 1/3] scripted-diff: test: rename `strCmd` to `command` -BEGIN VERIFY SCRIPT- sed -i 's/\bstrCmd\b/command/g' $(git grep -l strCmd) -END VERIFY SCRIPT- --- src/node/kernel_notifications.cpp | 8 ++++---- src/wallet/wallet.cpp | 18 +++++++++--------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/node/kernel_notifications.cpp b/src/node/kernel_notifications.cpp index 7224127c72..f148e2580c 100644 --- a/src/node/kernel_notifications.cpp +++ b/src/node/kernel_notifications.cpp @@ -30,8 +30,8 @@ static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); #if HAVE_SYSTEM - std::string strCmd = gArgs.GetArg("-alertnotify", ""); - if (strCmd.empty()) return; + std::string command = gArgs.GetArg("-alertnotify", ""); + if (command.empty()) return; // Alert text should be plain ascii coming from a trusted source, but to // be safe we first strip anything not in safeChars, then add single quotes around @@ -39,9 +39,9 @@ static void AlertNotify(const std::string& strMessage) std::string singleQuote("'"); std::string safeStatus = SanitizeString(strMessage); safeStatus = singleQuote+safeStatus+singleQuote; - ReplaceAll(strCmd, "%s", safeStatus); + ReplaceAll(command, "%s", safeStatus); - std::thread t(runCommand, strCmd); + std::thread t(runCommand, command); t.detach(); // thread runs free #endif } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 162d7f9ec7..d4ab95cab3 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1145,18 +1145,18 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const #if HAVE_SYSTEM // notify an external script when a wallet transaction comes in or is updated - std::string strCmd = m_notify_tx_changed_script; + std::string command = m_notify_tx_changed_script; - if (!strCmd.empty()) + if (!command.empty()) { - ReplaceAll(strCmd, "%s", hash.GetHex()); + ReplaceAll(command, "%s", hash.GetHex()); if (auto* conf = wtx.state()) { - ReplaceAll(strCmd, "%b", conf->confirmed_block_hash.GetHex()); - ReplaceAll(strCmd, "%h", ToString(conf->confirmed_block_height)); + ReplaceAll(command, "%b", conf->confirmed_block_hash.GetHex()); + ReplaceAll(command, "%h", ToString(conf->confirmed_block_height)); } else { - ReplaceAll(strCmd, "%b", "unconfirmed"); - ReplaceAll(strCmd, "%h", "-1"); + ReplaceAll(command, "%b", "unconfirmed"); + ReplaceAll(command, "%h", "-1"); } #ifndef WIN32 // Substituting the wallet name isn't currently supported on windows @@ -1164,9 +1164,9 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-537384875 // A few ways it could be implemented in the future are described in: // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-461288094 - ReplaceAll(strCmd, "%w", ShellEscape(GetName())); + ReplaceAll(command, "%w", ShellEscape(GetName())); #endif - std::thread t(runCommand, strCmd); + std::thread t(runCommand, command); t.detach(); // thread runs free } #endif From f1e300838a8423eb9f496cb234b44fe062b7a7c3 Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Fri, 17 Dec 2021 18:49:40 +0000 Subject: [PATCH 2/3] Support multiple -*notify commands --- src/init.cpp | 22 +++++++++------- src/node/kernel_notifications.cpp | 12 +++++---- src/wallet/wallet.cpp | 43 ++++++++++++++++++------------- src/wallet/wallet.h | 2 +- 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/init.cpp b/src/init.cpp index 42331d37e8..2b78447d3f 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -658,9 +658,8 @@ static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex) #if HAVE_SYSTEM static void StartupNotify(const ArgsManager& args) { - std::string cmd = args.GetArg("-startupnotify", ""); - if (!cmd.empty()) { - std::thread t(runCommand, cmd); + for (std::string command : args.GetArgs("-startupnotify")) { + std::thread t(runCommand, command); t.detach(); // thread runs free } } @@ -1671,14 +1670,17 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) } #if HAVE_SYSTEM - const std::string block_notify = args.GetArg("-blocknotify", ""); - if (!block_notify.empty()) { - uiInterface.NotifyBlockTip_connect([block_notify](SynchronizationState sync_state, const CBlockIndex* pBlockIndex) { + if (args.IsArgSet("-blocknotify")) { + auto blocknotify_commands = args.GetArgs("-blocknotify"); + uiInterface.NotifyBlockTip_connect([blocknotify_commands](SynchronizationState sync_state, const CBlockIndex* pBlockIndex) { if (sync_state != SynchronizationState::POST_INIT || !pBlockIndex) return; - std::string command = block_notify; - ReplaceAll(command, "%s", pBlockIndex->GetBlockHash().GetHex()); - std::thread t(runCommand, command); - t.detach(); // thread runs free + const std::string blockhash_hex = pBlockIndex->GetBlockHash().GetHex(); + for (std::string command : blocknotify_commands) { + ReplaceAll(command, "%s", blockhash_hex); + + std::thread t(runCommand, command); + t.detach(); // thread runs free + } }); } #endif diff --git a/src/node/kernel_notifications.cpp b/src/node/kernel_notifications.cpp index f148e2580c..d619217288 100644 --- a/src/node/kernel_notifications.cpp +++ b/src/node/kernel_notifications.cpp @@ -30,8 +30,7 @@ static void AlertNotify(const std::string& strMessage) { uiInterface.NotifyAlertChanged(); #if HAVE_SYSTEM - std::string command = gArgs.GetArg("-alertnotify", ""); - if (command.empty()) return; + if (!gArgs.IsArgSet("-alertnotify")) return; // Alert text should be plain ascii coming from a trusted source, but to // be safe we first strip anything not in safeChars, then add single quotes around @@ -39,10 +38,13 @@ static void AlertNotify(const std::string& strMessage) std::string singleQuote("'"); std::string safeStatus = SanitizeString(strMessage); safeStatus = singleQuote+safeStatus+singleQuote; - ReplaceAll(command, "%s", safeStatus); - std::thread t(runCommand, command); - t.detach(); // thread runs free + for (std::string command : gArgs.GetArgs("-alertnotify")) { + ReplaceAll(command, "%s", safeStatus); + + std::thread t(runCommand, command); + t.detach(); // thread runs free + } #endif } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d4ab95cab3..a8f25b1136 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1145,29 +1145,36 @@ CWalletTx* CWallet::AddToWallet(CTransactionRef tx, const TxState& state, const #if HAVE_SYSTEM // notify an external script when a wallet transaction comes in or is updated - std::string command = m_notify_tx_changed_script; - - if (!command.empty()) - { - ReplaceAll(command, "%s", hash.GetHex()); - if (auto* conf = wtx.state()) - { - ReplaceAll(command, "%b", conf->confirmed_block_hash.GetHex()); - ReplaceAll(command, "%h", ToString(conf->confirmed_block_height)); - } else { - ReplaceAll(command, "%b", "unconfirmed"); - ReplaceAll(command, "%h", "-1"); - } -#ifndef WIN32 + if (!m_notify_tx_changed_scripts.empty()) { +#ifdef WIN32 // Substituting the wallet name isn't currently supported on windows // because windows shell escaping has not been implemented yet: // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-537384875 // A few ways it could be implemented in the future are described in: // https://github.com/bitcoin/bitcoin/pull/13339#issuecomment-461288094 - ReplaceAll(command, "%w", ShellEscape(GetName())); + const std::string walletname_escaped = "wallet_name_substitution_is_not_available_on_Windows"; +#else + const std::string walletname_escaped = ShellEscape(GetName()); #endif - std::thread t(runCommand, command); - t.detach(); // thread runs free + const std::string txid_hex = hash.GetHex(); + std::string blockhash_hex, blockheight_str; + if (auto* conf = wtx.state()) { + blockhash_hex = conf->confirmed_block_hash.GetHex(); + blockheight_str = ToString(conf->confirmed_block_height); + } else { + blockhash_hex = "unconfirmed"; + blockheight_str = "-1"; + } + + for (std::string command : m_notify_tx_changed_scripts) { + ReplaceAll(command, "%s", txid_hex); + ReplaceAll(command, "%b", blockhash_hex); + ReplaceAll(command, "%h", blockheight_str); + ReplaceAll(command, "%w", walletname_escaped); + + std::thread t(runCommand, command); + t.detach(); // thread runs free + } } #endif @@ -2868,7 +2875,7 @@ std::shared_ptr CWallet::Create(WalletContext& context, const std::stri // should be possible to use std::allocate_shared. std::shared_ptr walletInstance(new CWallet(chain, name, std::move(database)), ReleaseWallet); walletInstance->m_keypool_size = std::max(args.GetIntArg("-keypool", DEFAULT_KEYPOOL_SIZE), int64_t{1}); - walletInstance->m_notify_tx_changed_script = args.GetArg("-walletnotify", ""); + walletInstance->m_notify_tx_changed_scripts = args.GetArgs("-walletnotify"); // Load wallet bool rescan_required = false; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 9333493a6e..1917aca476 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -723,7 +723,7 @@ public: int64_t m_keypool_size{DEFAULT_KEYPOOL_SIZE}; /** Notify external script when a wallet transaction comes in or is updated (handled by -walletnotify) */ - std::string m_notify_tx_changed_script; + std::vector m_notify_tx_changed_scripts; size_t KeypoolCountExternalKeys() const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); bool TopUpKeyPool(unsigned int kpSize = 0); From c0a914fc7d31512015aad83c9874cb5d6f6c373a Mon Sep 17 00:00:00 2001 From: Luke Dashjr Date: Tue, 10 Oct 2023 01:45:03 +0000 Subject: [PATCH 3/3] init: Optimise -startupnotify slightly --- src/init.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/init.cpp b/src/init.cpp index 2b78447d3f..91ef783737 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -658,7 +658,7 @@ static void BlockNotifyGenesisWait(const CBlockIndex* pBlockIndex) #if HAVE_SYSTEM static void StartupNotify(const ArgsManager& args) { - for (std::string command : args.GetArgs("-startupnotify")) { + for (const std::string& command : args.GetArgs("-startupnotify")) { std::thread t(runCommand, command); t.detach(); // thread runs free }