aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/common/notify.cpp27
-rw-r--r--src/common/notify.h2
-rw-r--r--src/common/spawn.cpp3
-rw-r--r--src/cryptonote_core/blockchain.cpp7
-rw-r--r--src/cryptonote_core/blockchain.h10
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp18
-rw-r--r--src/daemon/command_parser_executor.cpp29
-rw-r--r--src/daemon/command_server.cpp1
-rw-r--r--src/daemon/rpc_command_executor.cpp20
-rw-r--r--src/daemon/rpc_command_executor.h2
-rw-r--r--src/wallet/api/subaddress_account.cpp2
-rw-r--r--src/wallet/wallet2.cpp15
12 files changed, 117 insertions, 19 deletions
diff --git a/src/common/notify.cpp b/src/common/notify.cpp
index cadc68ea7..c3165fb05 100644
--- a/src/common/notify.cpp
+++ b/src/common/notify.cpp
@@ -27,11 +27,15 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <boost/algorithm/string.hpp>
+#include <stdarg.h>
#include "misc_log_ex.h"
#include "file_io_utils.h"
#include "spawn.h"
#include "notify.h"
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "notify"
+
namespace tools
{
@@ -46,15 +50,32 @@ Notify::Notify(const char *spec)
boost::split(args, spec, boost::is_any_of(" "));
CHECK_AND_ASSERT_THROW_MES(args.size() > 0, "Failed to parse spec");
+ if (strchr(spec, '\'') || strchr(spec, '\"') || strchr(spec, '\\'))
+ MWARNING("A notification spec contains a quote or backslash: note that these are handled verbatim, which may not be the intent");
filename = args[0];
CHECK_AND_ASSERT_THROW_MES(epee::file_io_utils::is_file_exist(filename), "File not found: " << filename);
}
-int Notify::notify(const char *parameter)
+static void replace(std::vector<std::string> &v, const char *tag, const char *s)
+{
+ for (std::string &str: v)
+ boost::replace_all(str, tag, s);
+}
+
+int Notify::notify(const char *tag, const char *s, ...)
{
std::vector<std::string> margs = args;
- for (std::string &s: margs)
- boost::replace_all(s, "%s", parameter);
+
+ replace(margs, tag, s);
+
+ va_list ap;
+ va_start(ap, s);
+ while ((tag = va_arg(ap, const char*)))
+ {
+ s = va_arg(ap, const char*);
+ replace(margs, tag, s);
+ }
+ va_end(ap);
return tools::spawn(filename.c_str(), margs, false);
}
diff --git a/src/common/notify.h b/src/common/notify.h
index 81aacebb0..f813e8def 100644
--- a/src/common/notify.h
+++ b/src/common/notify.h
@@ -39,7 +39,7 @@ class Notify
public:
Notify(const char *spec);
- int notify(const char *parameter);
+ int notify(const char *tag, const char *s, ...);
private:
std::string filename;
diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp
index b2d03f62f..e03552f8c 100644
--- a/src/common/spawn.cpp
+++ b/src/common/spawn.cpp
@@ -42,6 +42,9 @@
#include "util.h"
#include "spawn.h"
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "spawn"
+
namespace tools
{
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 9f1e2a0c0..41357e72e 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -1073,6 +1073,11 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::
m_hardfork->reorganize_from_chain_height(split_height);
+ std::shared_ptr<tools::Notify> reorg_notify = m_reorg_notify;
+ if (reorg_notify)
+ reorg_notify->notify("%s", std::to_string(split_height).c_str(), "%h", std::to_string(m_db->height()).c_str(),
+ "%n", std::to_string(m_db->height() - split_height).c_str(), NULL);
+
MGINFO_GREEN("REORGANIZE SUCCESS! on height: " << split_height << ", new blockchain size: " << m_db->height());
return true;
}
@@ -3701,7 +3706,7 @@ leave:
std::shared_ptr<tools::Notify> block_notify = m_block_notify;
if (block_notify)
- block_notify->notify(epee::string_tools::pod_to_hex(id).c_str());
+ block_notify->notify("%s", epee::string_tools::pod_to_hex(id).c_str(), NULL);
return true;
}
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 4952116ac..c742bec91 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -731,11 +731,18 @@ namespace cryptonote
/**
* @brief sets a block notify object to call for every new block
*
- * @param notify the notify object to cal at every new block
+ * @param notify the notify object to call at every new block
*/
void set_block_notify(const std::shared_ptr<tools::Notify> &notify) { m_block_notify = notify; }
/**
+ * @brief sets a reorg notify object to call for every reorg
+ *
+ * @param notify the notify object to call at every reorg
+ */
+ void set_reorg_notify(const std::shared_ptr<tools::Notify> &notify) { m_reorg_notify = notify; }
+
+ /**
* @brief Put DB in safe sync mode
*/
void safesyncmode(const bool onoff);
@@ -1077,6 +1084,7 @@ namespace cryptonote
bool m_btc_valid;
std::shared_ptr<tools::Notify> m_block_notify;
+ std::shared_ptr<tools::Notify> m_reorg_notify;
/**
* @brief collects the keys for all outputs being "spent" as an input
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 48c607ff1..1513bb750 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -185,6 +185,13 @@ namespace cryptonote
, "Prune blockchain"
, false
};
+ static const command_line::arg_descriptor<std::string> arg_reorg_notify = {
+ "reorg-notify"
+ , "Run a program for each reorg, '%s' will be replaced by the split height, "
+ "'%h' will be replaced by the new blockchain height, and '%n' will be "
+ "replaced by the number of new blocks in the new chain"
+ , ""
+ };
//-----------------------------------------------------------------------------------------------
core::core(i_cryptonote_protocol* pprotocol):
@@ -300,6 +307,7 @@ namespace cryptonote
command_line::add_arg(desc, arg_pad_transactions);
command_line::add_arg(desc, arg_block_notify);
command_line::add_arg(desc, arg_prune_blockchain);
+ command_line::add_arg(desc, arg_reorg_notify);
miner::init_options(desc);
BlockchainDB::init_options(desc);
@@ -582,6 +590,16 @@ namespace cryptonote
MERROR("Failed to parse block notify spec");
}
+ try
+ {
+ if (!command_line::is_arg_defaulted(vm, arg_reorg_notify))
+ m_blockchain_storage.set_reorg_notify(std::shared_ptr<tools::Notify>(new tools::Notify(command_line::get_arg(vm, arg_reorg_notify).c_str())));
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to parse reorg notify spec");
+ }
+
const std::pair<uint8_t, uint64_t> regtest_hard_forks[3] = {std::make_pair(1, 0), std::make_pair(Blockchain::get_hard_fork_heights(MAINNET).back().version, 1), std::make_pair(0, 0)};
const cryptonote::test_options regtest_test_options = {
regtest_hard_forks
diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp
index 37cb55ec8..73f33a674 100644
--- a/src/daemon/command_parser_executor.cpp
+++ b/src/daemon/command_parser_executor.cpp
@@ -48,9 +48,34 @@ t_command_parser_executor::t_command_parser_executor(
bool t_command_parser_executor::print_peer_list(const std::vector<std::string>& args)
{
- if (!args.empty()) return false;
+ if (args.size() > 3)
+ {
+ std::cout << "use: print_pl [white] [gray] [<limit>]" << std::endl;
+ return true;
+ }
+
+ bool white = false;
+ bool gray = false;
+ size_t limit = 0;
+ for (size_t i = 0; i < args.size(); ++i)
+ {
+ if (args[i] == "white")
+ {
+ white = true;
+ }
+ else if (args[i] == "gray")
+ {
+ gray = true;
+ }
+ else if (!epee::string_tools::get_xtype_from_string(limit, args[i]))
+ {
+ std::cout << "unexpected argument: " << args[i] << std::endl;
+ return true;
+ }
+ }
- return m_executor.print_peer_list();
+ const bool print_both = !white && !gray;
+ return m_executor.print_peer_list(white | print_both, gray | print_both, limit);
}
bool t_command_parser_executor::print_peer_list_stats(const std::vector<std::string>& args)
diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp
index 786d1a601..96dea76b6 100644
--- a/src/daemon/command_server.cpp
+++ b/src/daemon/command_server.cpp
@@ -64,6 +64,7 @@ t_command_server::t_command_server(
m_command_lookup.set_handler(
"print_pl"
, std::bind(&t_command_parser_executor::print_peer_list, &m_parser, p::_1)
+ , "print_pl [white] [gray] [<limit>]"
, "Print the current peer list."
);
m_command_lookup.set_handler(
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index c2d30fcce..839350522 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -156,7 +156,7 @@ t_rpc_command_executor::~t_rpc_command_executor()
}
}
-bool t_rpc_command_executor::print_peer_list() {
+bool t_rpc_command_executor::print_peer_list(bool white, bool gray, size_t limit) {
cryptonote::COMMAND_RPC_GET_PEER_LIST::request req;
cryptonote::COMMAND_RPC_GET_PEER_LIST::response res;
@@ -177,14 +177,24 @@ bool t_rpc_command_executor::print_peer_list() {
}
}
- for (auto & peer : res.white_list)
+ if (white)
{
- print_peer("white", peer);
+ auto peer = res.white_list.cbegin();
+ const auto end = limit ? peer + std::min(limit, res.white_list.size()) : res.white_list.cend();
+ for (; peer != end; ++peer)
+ {
+ print_peer("white", *peer);
+ }
}
- for (auto & peer : res.gray_list)
+ if (gray)
{
- print_peer("gray", peer);
+ auto peer = res.gray_list.cbegin();
+ const auto end = limit ? peer + std::min(limit, res.gray_list.size()) : res.gray_list.cend();
+ for (; peer != end; ++peer)
+ {
+ print_peer("gray", *peer);
+ }
}
return true;
diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h
index de743065b..b1e9828a0 100644
--- a/src/daemon/rpc_command_executor.h
+++ b/src/daemon/rpc_command_executor.h
@@ -67,7 +67,7 @@ public:
~t_rpc_command_executor();
- bool print_peer_list();
+ bool print_peer_list(bool white = true, bool gray = true, size_t limit = 0);
bool print_peer_list_stats();
diff --git a/src/wallet/api/subaddress_account.cpp b/src/wallet/api/subaddress_account.cpp
index 19ed8fb38..4765465c3 100644
--- a/src/wallet/api/subaddress_account.cpp
+++ b/src/wallet/api/subaddress_account.cpp
@@ -62,7 +62,7 @@ void SubaddressAccountImpl::refresh()
{
m_rows.push_back(new SubaddressAccountRow(
i,
- m_wallet->m_wallet->get_subaddress_as_str({i,0}).substr(0,6),
+ m_wallet->m_wallet->get_subaddress_as_str({i,0}),
m_wallet->m_wallet->get_subaddress_label({i,0}),
cryptonote::print_money(m_wallet->m_wallet->balance(i)),
cryptonote::print_money(m_wallet->m_wallet->unlocked_balance(i))
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index a8fe9c7cb..c02d10ab4 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -628,7 +628,7 @@ std::string strjoin(const std::vector<size_t> &V, const char *sep)
return ss.str();
}
-static void emplace_or_replace(std::unordered_multimap<crypto::hash, tools::wallet2::pool_payment_details> &container,
+static bool emplace_or_replace(std::unordered_multimap<crypto::hash, tools::wallet2::pool_payment_details> &container,
const crypto::hash &key, const tools::wallet2::pool_payment_details &pd)
{
auto range = container.equal_range(key);
@@ -637,10 +637,11 @@ static void emplace_or_replace(std::unordered_multimap<crypto::hash, tools::wall
if (i->second.m_pd.m_tx_hash == pd.m_pd.m_tx_hash && i->second.m_pd.m_subaddr_index == pd.m_pd.m_subaddr_index)
{
i->second = pd;
- return;
+ return false;
}
}
container.emplace(key, pd);
+ return true;
}
void drop_from_short_history(std::list<crypto::hash> &short_chain_history, size_t N)
@@ -2015,6 +2016,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
return;
}
+ bool all_same = true;
for (const auto& i : tx_money_got_in_outs)
{
payment_details payment;
@@ -2027,7 +2029,8 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
payment.m_coinbase = miner_tx;
payment.m_subaddr_index = i.first;
if (pool) {
- emplace_or_replace(m_unconfirmed_payments, payment_id, pool_payment_details{payment, double_spend_seen});
+ if (emplace_or_replace(m_unconfirmed_payments, payment_id, pool_payment_details{payment, double_spend_seen}))
+ all_same = false;
if (0 != m_callback)
m_callback->on_unconfirmed_money_received(height, txid, tx, payment.m_amount, payment.m_subaddr_index);
}
@@ -2035,13 +2038,17 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
m_payments.emplace(payment_id, payment);
LOG_PRINT_L2("Payment found in " << (pool ? "pool" : "block") << ": " << payment_id << " / " << payment.m_tx_hash << " / " << payment.m_amount);
}
+
+ // if it's a pool tx and we already had it, don't notify again
+ if (pool && all_same)
+ notify = false;
}
if (notify)
{
std::shared_ptr<tools::Notify> tx_notify = m_tx_notify;
if (tx_notify)
- tx_notify->notify(epee::string_tools::pod_to_hex(txid).c_str());
+ tx_notify->notify("%s", epee::string_tools::pod_to_hex(txid).c_str(), NULL);
}
}
//----------------------------------------------------------------------------------------------------