From 50af3579ee735ad6a9d95014f2d9b5141d05769c Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 19 May 2018 23:53:05 +0100 Subject: [PATCH] alt_chain_info can now give more info about a particular alt chain --- src/cryptonote_core/blockchain.cpp | 11 +++++---- src/cryptonote_core/blockchain.h | 2 +- src/daemon/command_parser_executor.cpp | 6 ++--- src/daemon/command_server.cpp | 1 + src/daemon/rpc_command_executor.cpp | 32 ++++++++++++++++++++----- src/daemon/rpc_command_executor.h | 2 +- src/rpc/core_rpc_server.cpp | 16 +++++++++++-- src/rpc/core_rpc_server_commands_defs.h | 6 ++++- 8 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index fbb2a2223..5d7022917 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -4393,9 +4393,9 @@ std::map> Blockchain:: get_ou return m_db->get_output_histogram(amounts, unlocked, recent_cutoff, min_count); } -std::list> Blockchain::get_alternative_chains() const +std::list>> Blockchain::get_alternative_chains() const { - std::list> chains; + std::list>> chains; for (const auto &i: m_alternative_chains) { @@ -4411,15 +4411,16 @@ std::list> Blockchain::get_a } if (!found) { - uint64_t length = 1; + std::vector chain; auto h = i.second.bl.prev_id; + chain.push_back(top); blocks_ext_by_hash::const_iterator prev; while ((prev = m_alternative_chains.find(h)) != m_alternative_chains.end()) { + chain.push_back(h); h = prev->second.bl.prev_id; - ++length; } - chains.push_back(std::make_pair(i.second, length)); + chains.push_back(std::make_pair(i.second, chain)); } } return chains; diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index ef736d1e7..d5abba998 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -939,7 +939,7 @@ namespace cryptonote * * @return a list of chains */ - std::list> get_alternative_chains() const; + std::list>> get_alternative_chains() const; void add_txpool_tx(transaction &tx, const txpool_tx_meta_t &meta); void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t &meta); diff --git a/src/daemon/command_parser_executor.cpp b/src/daemon/command_parser_executor.cpp index 34d9fb4c8..36e040ab5 100644 --- a/src/daemon/command_parser_executor.cpp +++ b/src/daemon/command_parser_executor.cpp @@ -599,13 +599,13 @@ bool t_command_parser_executor::print_coinbase_tx_sum(const std::vector& args) { - if(args.size()) + if(args.size() > 1) { - std::cout << "No parameters allowed" << std::endl; + std::cout << "usage: alt_chain_info [block_hash]" << std::endl; return false; } - return m_executor.alt_chain_info(); + return m_executor.alt_chain_info(args.size() == 1 ? args[0] : ""); } bool t_command_parser_executor::print_blockchain_dynamic_stats(const std::vector& args) diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 144603597..35504f2c9 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -255,6 +255,7 @@ t_command_server::t_command_server( m_command_lookup.set_handler( "alt_chain_info" , std::bind(&t_command_parser_executor::alt_chain_info, &m_parser, p::_1) + , "alt_chain_info [blockhash]" , "Print the information about alternative chains." ); m_command_lookup.set_handler( diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 487853441..0b5b05d3d 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -1628,7 +1628,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() +bool t_rpc_command_executor::alt_chain_info(const std::string &tip) { cryptonote::COMMAND_RPC_GET_INFO::request ireq; cryptonote::COMMAND_RPC_GET_INFO::response ires; @@ -1663,12 +1663,32 @@ bool t_rpc_command_executor::alt_chain_info() } } - tools::msg_writer() << boost::lexical_cast(res.chains.size()) << " alternate chains found:"; - for (const auto &chain: res.chains) + if (tip.empty()) { - 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; + tools::msg_writer() << boost::lexical_cast(res.chains.size()) << " alternate chains found:"; + for (const auto &chain: res.chains) + { + 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; + } + } + else + { + const auto i = std::find_if(res.chains.begin(), res.chains.end(), [&tip](cryptonote::COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info &info){ return info.block_hash == tip; }); + if (i != res.chains.end()) + { + const auto &chain = *i; + tools::success_msg_writer() << "Found alternate chain with tip " << tip; + 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 << ":"; + for (const std::string &block_id: chain.block_hashes) + tools::msg_writer() << " " << block_id; + tools::msg_writer() << "Chain parent on main chain: " << chain.main_chain_parent_block; + } + else + tools::fail_msg_writer() << "Block hash " << tip << " is not the tip of any known alternate chain"; } return true; } diff --git a/src/daemon/rpc_command_executor.h b/src/daemon/rpc_command_executor.h index 46168c93b..9e6010c5b 100644 --- a/src/daemon/rpc_command_executor.h +++ b/src/daemon/rpc_command_executor.h @@ -143,7 +143,7 @@ public: bool print_coinbase_tx_sum(uint64_t height, uint64_t count); - bool alt_chain_info(); + bool alt_chain_info(const std::string &tip); bool print_blockchain_dynamic_stats(uint64_t nblocks); diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index dc7b6b30f..e87078398 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1774,10 +1774,22 @@ namespace cryptonote PERF_TIMER(on_get_alternate_chains); try { - std::list> chains = m_core.get_blockchain_storage().get_alternative_chains(); + std::list>> chains = m_core.get_blockchain_storage().get_alternative_chains(); for (const auto &i: chains) { - res.chains.push_back(COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info{epee::string_tools::pod_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second, i.first.cumulative_difficulty}); + res.chains.push_back(COMMAND_RPC_GET_ALTERNATE_CHAINS::chain_info{epee::string_tools::pod_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second.size(), i.first.cumulative_difficulty, {}, std::string()}); + res.chains.back().block_hashes.reserve(i.second.size()); + for (const crypto::hash &block_id: i.second) + res.chains.back().block_hashes.push_back(epee::string_tools::pod_to_hex(block_id)); + if (i.first.height < i.second.size()) + { + res.status = "Error finding alternate chain attachment point"; + return true; + } + cryptonote::block main_chain_parent_block; + try { main_chain_parent_block = m_core.get_blockchain_storage().get_db().get_block_from_height(i.first.height - i.second.size()); } + catch (const std::exception &e) { res.status = "Error finding alternate chain attachment point"; return true; } + res.chains.back().main_chain_parent_block = epee::string_tools::pod_to_hex(get_block_hash(main_chain_parent_block)); } res.status = CORE_RPC_STATUS_OK; } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 70e186848..2fb7e9ea3 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -49,7 +49,7 @@ namespace cryptonote // advance which version they will stop working with // Don't go over 32767 for any of these #define CORE_RPC_VERSION_MAJOR 1 -#define CORE_RPC_VERSION_MINOR 20 +#define CORE_RPC_VERSION_MINOR 21 #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) @@ -2086,12 +2086,16 @@ namespace cryptonote uint64_t height; uint64_t length; uint64_t difficulty; + std::vector block_hashes; + std::string main_chain_parent_block; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(block_hash) KV_SERIALIZE(height) KV_SERIALIZE(length) KV_SERIALIZE(difficulty) + KV_SERIALIZE(block_hashes) + KV_SERIALIZE(main_chain_parent_block) END_KV_SERIALIZE_MAP() };