diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 17b945c9a..a8a3db45a 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -672,11 +672,38 @@ bool t_command_parser_executor::alt_chain_info(const std::vector& a { if(args.size() > 1) { - std::cout << "usage: alt_chain_info [block_hash]" << std::endl; + std::cout << "usage: alt_chain_info [block_hash|>N|-N]" << std::endl; return false; } - return m_executor.alt_chain_info(args.size() == 1 ? args[0] : ""); + std::string tip; + size_t above = 0; + uint64_t last_blocks = 0; + if (args.size() == 1) + { + if (args[0].size() > 0 && args[0][0] == '>') + { + if (!epee::string_tools::get_xtype_from_string(above, args[0].c_str() + 1)) + { + std::cout << "invalid above parameter" << std::endl; + return false; + } + } + else if (args[0].size() > 0 && args[0][0] == '-') + { + if (!epee::string_tools::get_xtype_from_string(last_blocks, args[0].c_str() + 1)) + { + std::cout << "invalid last_blocks parameter" << std::endl; + return false; + } + } + else + { + tip = args[0]; + } + } + + return m_executor.alt_chain_info(tip, above, last_blocks); } bool t_command_parser_executor::print_blockchain_dynamic_stats(const std::vector& args) diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 054b956ab..51fbd8628 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -1823,7 +1823,7 @@ bool t_rpc_command_executor::print_coinbase_tx_sum(uint64_t height, uint64_t cou return true; } -bool t_rpc_command_executor::alt_chain_info(const std::string &tip) +bool t_rpc_command_executor::alt_chain_info(const std::string &tip, size_t above, uint64_t last_blocks) { cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; @@ -1860,12 +1860,24 @@ bool t_rpc_command_executor::alt_chain_info(const std::string &tip) if (tip.empty()) { - tools::msg_writer() << boost::lexical_cast(res.chains.size()) << " alternate chains found:"; auto chains = res.chains; std::sort(chains.begin(), chains.end(), [](const cryptonote::COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info &info0, cryptonote::COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info &info1){ return info0.height < info1.height; }); - for (const auto &chain: chains) - { - uint64_t start_height = (chain.height - chain.length + 1); + std::vector display; + for (size_t i = 0; i < chains.size(); ++i) + { + const auto &chain = chains[i]; + if (chain.length <= above) + continue; + const uint64_t start_height = (chain.height - chain.length + 1); + if (last_blocks > 0 && ires.height - 1 - start_height >= last_blocks) + continue; + display.push_back(i); + } + tools::msg_writer() << boost::lexical_cast(display.size()) << " alternate chains found:"; + for (const size_t idx: display) + { + const auto &chain = chains[idx]; + const uint64_t start_height = (chain.height - chain.length + 1); tools::msg_writer() << chain.length << " blocks long, from height " << start_height << " (" << (ires.height - start_height - 1) << " deep), diff " << chain.difficulty << ": " << chain.block_hash; } diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index 3c2686b3f..96e742e1b 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -145,7 +145,7 @@ public: bool print_coinbase_tx_sum(uint64_t height, uint64_t count); - bool alt_chain_info(const std::string &tip); + bool alt_chain_info(const std::string &tip, size_t above, uint64_t last_blocks); bool print_blockchain_dynamic_stats(uint64_t nblocks);