From 28b6dbf2633f695b7bf85dba25cb678e898bc233 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 6 Feb 2019 17:48:08 +0000 Subject: [PATCH 1/5] notify: fix tokenizing being too strict --- src/common/notify.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/notify.cpp b/src/common/notify.cpp index c3165fb05..e2df5096d 100644 --- a/src/common/notify.cpp +++ b/src/common/notify.cpp @@ -48,7 +48,7 @@ Notify::Notify(const char *spec) { CHECK_AND_ASSERT_THROW_MES(spec, "Null spec"); - boost::split(args, spec, boost::is_any_of(" ")); + boost::split(args, spec, boost::is_any_of(" \t"), boost::token_compress_on); 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"); From d4fb9641e0a84ac6d6acb7d7f322ca22b8412a89 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 6 Feb 2019 17:09:28 +0000 Subject: [PATCH 2/5] core: add --block-rate-notify This runs a command whenever the block rate deviates too much from the expectation --- src/cryptonote_core/cryptonote_core.cpp | 31 +++++++++++++++++++++++++ src/cryptonote_core/cryptonote_core.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index bc01e2435..62efabf63 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -192,6 +192,18 @@ namespace cryptonote "replaced by the number of new blocks in the new chain" , "" }; + static const command_line::arg_descriptor arg_block_rate_notify = { + "block-rate-notify" + , "Run a program when the block rate undergoes large fluctuations. This might " + "be a sign of large amounts of hash rate going on and off the Monero network, " + "and thus be of potential interest in predicting attacks. %t will be replaced " + "by the number of minutes for the observation window, %b by the number of " + "blocks observed within that window, and %e by the number of blocks that was " + "expected in that window. It is suggested that this notification is used to " + "automatically increase the number of confirmations required before a payment " + "is acted upon." + , "" + }; //----------------------------------------------------------------------------------------------- core::core(i_cryptonote_protocol* pprotocol): @@ -308,6 +320,7 @@ namespace cryptonote command_line::add_arg(desc, arg_block_notify); command_line::add_arg(desc, arg_prune_blockchain); command_line::add_arg(desc, arg_reorg_notify); + command_line::add_arg(desc, arg_block_rate_notify); miner::init_options(desc); BlockchainDB::init_options(desc); @@ -600,6 +613,16 @@ namespace cryptonote MERROR("Failed to parse reorg notify spec"); } + try + { + if (!command_line::is_arg_defaulted(vm, arg_block_rate_notify)) + m_block_rate_notify.reset(new tools::Notify(command_line::get_arg(vm, arg_block_rate_notify).c_str())); + } + catch (const std::exception &e) + { + MERROR("Failed to parse block rate notify spec: " << e.what()); + } + const std::pair 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, @@ -1776,6 +1799,14 @@ namespace cryptonote if (p < threshold) { MWARNING("There were " << b << " blocks in the last " << seconds[n] / 60 << " minutes, there might be large hash rate changes, or we might be partitioned, cut off from the Monero network or under attack. Or it could be just sheer bad luck."); + + std::shared_ptr block_rate_notify = m_block_rate_notify; + if (block_rate_notify) + { + auto expected = seconds[n] / DIFFICULTY_TARGET_V2; + block_rate_notify->notify("%t", std::to_string(seconds[n] / 60).c_str(), "%b", std::to_string(b).c_str(), "%e", std::to_string(expected).c_str(), NULL); + } + break; // no need to look further } } diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 308924bb9..79d06662e 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -1062,6 +1062,8 @@ namespace cryptonote bool m_fluffy_blocks_enabled; bool m_offline; bool m_pad_transactions; + + std::shared_ptr m_block_rate_notify; }; } From 4d598e3d4d4f0be5fadb3fda73fcdbb7e2bef136 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 6 Feb 2019 19:04:47 +0000 Subject: [PATCH 3/5] core: add a few more block rate window sizes The 10 minute one will never trigger for 0 blocks, as it's still fairly likely to happen even without the actual hash rate changing much, so we add a 20 minute window, where it will (for 0 blocks) and a one hour window. --- src/cryptonote_core/cryptonote_core.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 62efabf63..f15901175 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1788,7 +1788,7 @@ namespace cryptonote const time_t now = time(NULL); const std::vector timestamps = m_blockchain_storage.get_last_block_timestamps(60); - static const unsigned int seconds[] = { 5400, 1800, 600 }; + static const unsigned int seconds[] = { 5400, 3600, 1800, 1200, 600 }; for (size_t n = 0; n < sizeof(seconds)/sizeof(seconds[0]); ++n) { unsigned int b = 0; From 356d813799d9266ec923659e02f84a06071722d7 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 6 Feb 2019 22:01:40 +0000 Subject: [PATCH 4/5] blockchain: include number of discarded blocks in --reorg-notify --- src/cryptonote_core/blockchain.cpp | 3 ++- src/cryptonote_core/cryptonote_core.cpp | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 42003921a..0de4d49de 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -1056,6 +1056,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list 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); + "%n", std::to_string(m_db->height() - split_height).c_str(), "%d", std::to_string(discarded_blocks).c_str(), NULL); MGINFO_GREEN("REORGANIZE SUCCESS! on height: " << split_height << ", new blockchain size: " << m_db->height()); return true; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index f15901175..7f25b6851 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -188,8 +188,9 @@ namespace cryptonote static const command_line::arg_descriptor 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" + "'%h' will be replaced by the new blockchain height, '%n' will be " + "replaced by the number of new blocks in the new chain, and '%d' will be " + "replaced by the number of blocks discarded from the old chain" , "" }; static const command_line::arg_descriptor arg_block_rate_notify = { From a17da7202bcd176a0134ebdaeba6fbce40e745fc Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Wed, 13 Feb 2019 14:04:09 +0000 Subject: [PATCH 5/5] Print the reason why a notification spec failed to parse --- src/cryptonote_core/cryptonote_core.cpp | 4 ++-- src/wallet/wallet2.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 7f25b6851..599f42774 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -601,7 +601,7 @@ namespace cryptonote } catch (const std::exception &e) { - MERROR("Failed to parse block notify spec"); + MERROR("Failed to parse block notify spec: " << e.what()); } try @@ -611,7 +611,7 @@ namespace cryptonote } catch (const std::exception &e) { - MERROR("Failed to parse reorg notify spec"); + MERROR("Failed to parse reorg notify spec: " << e.what()); } try diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index c02d10ab4..cfb1d8684 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -373,7 +373,7 @@ std::unique_ptr make_basic(const boost::program_options::variabl } catch (const std::exception &e) { - MERROR("Failed to parse tx notify spec"); + MERROR("Failed to parse tx notify spec: " << e.what()); } return wallet;