diff options
author | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-04-09 13:14:35 +0100 |
---|---|---|
committer | Antonio Juarez <antonio.maria.juarez@live.com> | 2014-04-09 13:14:35 +0100 |
commit | 9682a15400495ae490543e7e5af242ff5c4c9fa0 (patch) | |
tree | 63ba7287d8f679742a244413291d4334fc26b6e6 /src | |
parent | Improvements in JSON RPC (diff) | |
download | monero-9682a15400495ae490543e7e5af242ff5c4c9fa0.tar.xz |
Port mapping with UPnP
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 10 | ||||
-rw-r--r-- | src/cryptonote_core/checkpoints_create.h | 3 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 35 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 139 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.h | 20 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 93 | ||||
-rw-r--r-- | src/version.h.in | 4 |
7 files changed, 290 insertions, 14 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 600413f16..f890fcda9 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,3 +1,5 @@ +add_definitions(-DSTATICLIB) + file(GLOB_RECURSE COMMON common/*) file(GLOB_RECURSE CRYPTO crypto/*) file(GLOB_RECURSE CRYPTONOTE_CORE cryptonote_core/*) @@ -28,16 +30,16 @@ add_library(cryptonote_core ${CRYPTONOTE_CORE}) add_executable(daemon ${DAEMON} ${P2P} ${CRYPTONOTE_PROTOCOL}) add_executable(connectivity_tool ${CONN_TOOL}) add_executable(simpleminer ${MINER}) -target_link_libraries(daemon rpc cryptonote_core crypto common ${Boost_LIBRARIES}) +target_link_libraries(daemon rpc cryptonote_core crypto common upnpc-static ${Boost_LIBRARIES}) target_link_libraries(connectivity_tool cryptonote_core crypto common ${Boost_LIBRARIES}) target_link_libraries(simpleminer cryptonote_core crypto common ${Boost_LIBRARIES}) -add_dependencies(daemon version) add_library(rpc ${RPC}) add_library(wallet ${WALLET}) add_executable(simplewallet ${SIMPLEWALLET} ) -target_link_libraries(simplewallet wallet rpc cryptonote_core crypto common ${Boost_LIBRARIES}) -add_dependencies(simplewallet version) +target_link_libraries(simplewallet wallet rpc cryptonote_core crypto common upnpc-static ${Boost_LIBRARIES}) add_dependencies(daemon version) +add_dependencies(rpc version) +add_dependencies(simplewallet version) set_property(TARGET common crypto cryptonote_core rpc wallet PROPERTY FOLDER "libs") set_property(TARGET daemon simplewallet connectivity_tool simpleminer PROPERTY FOLDER "prog") diff --git a/src/cryptonote_core/checkpoints_create.h b/src/cryptonote_core/checkpoints_create.h index 3d539de98..6046a011e 100644 --- a/src/cryptonote_core/checkpoints_create.h +++ b/src/cryptonote_core/checkpoints_create.h @@ -21,7 +21,8 @@ namespace cryptonote { ADD_CHECKPOINT(390285, "e00bdc9bf407aeace2f3109de11889ed25894bf194231d075eddaec838097eb7"); ADD_CHECKPOINT(417000, "2dc96f8fc4d4a4d76b3ed06722829a7ab09d310584b8ecedc9b578b2c458a69f"); ADD_CHECKPOINT(427193, "00feabb08f2d5759ed04fd6b799a7513187478696bba2db2af10d4347134e311"); - + ADD_CHECKPOINT(453537, "d17de6916c5aa6ffcae575309c80b0f8fdcd0a84b5fa8e41a841897d4b5a4e97"); + return true; } } diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 2b46470d9..4c43f9dbf 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -15,6 +15,9 @@ #include "net/local_ip.h" #include "crypto/crypto.h" #include "storages/levin_abstract_invoke2.h" +#include <miniupnpc/miniupnpc.h> +#include <miniupnpc/upnpcommands.h> + #define NET_MAKE_IP(b1,b2,b3,b4) ((LPARAM)(((DWORD)(b1)<<24)+((DWORD)(b2)<<16)+((DWORD)(b3)<<8)+((DWORD)(b4)))) @@ -233,6 +236,38 @@ namespace nodetool LOG_PRINT_GREEN("Net service binded on " << m_bind_ip << ":" << m_listenning_port, LOG_LEVEL_0); if(m_external_port) LOG_PRINT_L0("External port defined as " << m_external_port); + + // Add UPnP port mapping + LOG_PRINT_L0("Attempting to add IGD port mapping."); + int result; + UPNPDev* deviceList = upnpDiscover(1000, NULL, NULL, 0, 0, &result); + UPNPUrls urls; + IGDdatas igdData; + char lanAddress[64]; + result = UPNP_GetValidIGD(deviceList, &urls, &igdData, lanAddress, sizeof lanAddress); + freeUPNPDevlist(deviceList); + if (result != 0) { + if (result == 1) { + std::ostringstream portString; + portString << m_listenning_port; + if (UPNP_AddPortMapping(urls.controlURL, igdData.first.servicetype, portString.str().c_str(), portString.str().c_str(), lanAddress, CRYPTONOTE_NAME, "TCP", 0, "0") != 0) { + LOG_ERROR("UPNP_AddPortMapping failed."); + } else { + LOG_PRINT_GREEN("Added IGD port mapping.", LOG_LEVEL_0); + } + } else if (result == 2) { + LOG_PRINT_L0("IGD was found but reported as not connected."); + } else if (result == 3) { + LOG_PRINT_L0("UPnP device was found but not recoginzed as IGD."); + } else { + LOG_ERROR("UPNP_GetValidIGD returned an unknown result code."); + } + + FreeUPNPUrls(&urls); + } else { + LOG_PRINT_L0("No IGD was found."); + } + return res; } //----------------------------------------------------------------------------------- diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 4c392c606..bab373c86 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -11,6 +11,7 @@ using namespace epee; #include "common/command_line.h" #include "cryptonote_core/cryptonote_format_utils.h" #include "cryptonote_core/account.h" +#include "cryptonote_core/cryptonote_basic_impl.h" #include "misc_language.h" #include "crypto/hash.h" #include "core_rpc_server_error_codes.h" @@ -413,6 +414,140 @@ namespace cryptonote return true; } //------------------------------------------------------------------------------------------------------------------------------ - - + uint64_t core_rpc_server::get_block_reward(const block& blk) + { + uint64_t reward = 0; + BOOST_FOREACH(const tx_out& out, blk.miner_tx.vout) + { + reward += out.amount; + } + return reward; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::fill_block_header_responce(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_responce& responce) + { + responce.major_version = blk.major_version; + responce.minor_version = blk.minor_version; + responce.timestamp = blk.timestamp; + responce.prev_hash = string_tools::pod_to_hex(blk.prev_id); + responce.nonce = blk.nonce; + responce.orphan_status = orphan_status; + responce.height = height; + responce.depth = m_core.get_current_blockchain_height() - height - 1; + responce.hash = string_tools::pod_to_hex(hash); + responce.difficulty = m_core.get_blockchain_storage().block_difficulty(height); + responce.reward = get_block_reward(blk); + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, connection_context& cntx) + { + if(!check_core_ready()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy."; + return false; + } + uint64_t last_block_height; + crypto::hash last_block_hash; + bool have_last_block_hash = m_core.get_blockchain_top(last_block_height, last_block_hash); + if (!have_last_block_hash) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't get last block hash."; + return false; + } + block last_block; + bool have_last_block = m_core.get_block_by_hash(last_block_hash, last_block); + if (!have_last_block) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't get last block."; + return false; + } + bool responce_filled = fill_block_header_responce(last_block, false, last_block_height, last_block_hash, res.block_header); + if (!responce_filled) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't produce valid response."; + return false; + } + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp, connection_context& cntx){ + if(!check_core_ready()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy."; + return false; + } + crypto::hash block_hash; + bool hash_parsed = parse_hash256(req.hash, block_hash); + if(!hash_parsed) + { + error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM; + error_resp.message = "Failed to parse hex representation of block hash. Hex = " + req.hash + '.'; + return false; + } + block blk; + bool have_block = m_core.get_block_by_hash(block_hash, blk); + if (!have_block) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't get block by hash. Hash = " + req.hash + '.'; + return false; + } + if (blk.miner_tx.vin.front().type() != typeid(txin_gen)) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: coinbase transaction in the block has the wrong type"; + return false; + } + uint64_t block_height = boost::get<txin_gen>(blk.miner_tx.vin.front()).height; + bool responce_filled = fill_block_header_responce(blk, false, block_height, block_hash, res.block_header); + if (!responce_filled) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't produce valid response."; + return false; + } + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ + bool core_rpc_server::on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp, connection_context& cntx){ + if(!check_core_ready()) + { + error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY; + error_resp.message = "Core is busy."; + return false; + } + if(m_core.get_current_blockchain_height() <= req.height) + { + error_resp.code = CORE_RPC_ERROR_CODE_TOO_BIG_HEIGHT; + error_resp.message = std::string("To big height: ") + std::to_string(req.height) + ", current blockchain height = " + std::to_string(m_core.get_current_blockchain_height()); + return false; + } + crypto::hash block_hash = m_core.get_block_id_by_height(req.height); + block blk; + bool have_block = m_core.get_block_by_hash(block_hash, blk); + if (!have_block) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't get block by height. Height = " + req.height + '.'; + return false; + } + bool responce_filled = fill_block_header_responce(blk, false, req.height, block_hash, res.block_header); + if (!responce_filled) + { + error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR; + error_resp.message = "Internal error: can't produce valid response."; + return false; + } + res.status = CORE_RPC_STATUS_OK; + return true; + } + //------------------------------------------------------------------------------------------------------------------------------ } diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h index fb3e92216..7b14e741a 100644 --- a/src/rpc/core_rpc_server.h +++ b/src/rpc/core_rpc_server.h @@ -42,10 +42,13 @@ namespace cryptonote MAP_URI_AUTO_JON2("/stop_mining", on_stop_mining, COMMAND_RPC_STOP_MINING) MAP_URI_AUTO_JON2("/getinfo", on_get_info, COMMAND_RPC_GET_INFO) BEGIN_JSON_RPC_MAP("/json_rpc") - MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) - MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) - MAP_JON_RPC_WE("getblocktemplate",on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE) - MAP_JON_RPC_WE("submitblock", on_submitblock, COMMAND_RPC_SUBMITBLOCK) + MAP_JON_RPC("getblockcount", on_getblockcount, COMMAND_RPC_GETBLOCKCOUNT) + MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH) + MAP_JON_RPC_WE("getblocktemplate", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE) + MAP_JON_RPC_WE("submitblock", on_submitblock, COMMAND_RPC_SUBMITBLOCK) + MAP_JON_RPC_WE("getlastblockheader", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER) + MAP_JON_RPC_WE("getblockheaderbyhash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH) + MAP_JON_RPC_WE("getblockheaderbyheight", on_get_block_header_by_height, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT) END_JSON_RPC_MAP() END_URI_MAP2() @@ -64,10 +67,17 @@ namespace cryptonote bool on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); bool on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); bool on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); + bool on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); + bool on_get_block_header_by_hash(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); + bool on_get_block_header_by_height(const COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::request& req, COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT::response& res, epee::json_rpc::error& error_resp, connection_context& cntx); //----------------------- bool handle_command_line(const boost::program_options::variables_map& vm); bool check_core_ready(); - + + //utils + uint64_t get_block_reward(const block& blk); + bool fill_block_header_responce(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_responce& responce); + core& m_core; nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p; std::string m_port; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 5e8210775..d67ebfdd7 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -5,6 +5,7 @@ #pragma once #include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "cryptonote_core/cryptonote_basic.h" +#include "cryptonote_core/difficulty.h" #include "crypto/hash.h" namespace cryptonote @@ -330,8 +331,100 @@ namespace cryptonote END_KV_SERIALIZE_MAP() }; }; + + struct block_header_responce + { + uint8_t major_version; + uint8_t minor_version; + uint64_t timestamp; + std::string prev_hash; + uint32_t nonce; + bool orphan_status; + uint64_t height; + uint64_t depth; + std::string hash; + difficulty_type difficulty; + uint64_t reward; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(major_version) + KV_SERIALIZE(minor_version) + KV_SERIALIZE(timestamp) + KV_SERIALIZE(prev_hash) + KV_SERIALIZE(nonce) + KV_SERIALIZE(orphan_status) + KV_SERIALIZE(height) + KV_SERIALIZE(depth) + KV_SERIALIZE(hash) + KV_SERIALIZE(difficulty) + KV_SERIALIZE(reward) + END_KV_SERIALIZE_MAP() + }; + + struct COMMAND_RPC_GET_LAST_BLOCK_HEADER + { + typedef std::list<std::string> request; + + struct response + { + std::string status; + block_header_responce block_header; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(block_header) + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + + }; + + struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH + { + struct request + { + std::string hash; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(hash) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + block_header_responce block_header; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(block_header) + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + }; + struct COMMAND_RPC_GET_BLOCK_HEADER_BY_HEIGHT + { + struct request + { + uint64_t height; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(height) + END_KV_SERIALIZE_MAP() + }; + + struct response + { + std::string status; + block_header_responce block_header; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(block_header) + KV_SERIALIZE(status) + END_KV_SERIALIZE_MAP() + }; + + }; } diff --git a/src/version.h.in b/src/version.h.in index 2fc114a34..331657755 100644 --- a/src/version.h.in +++ b/src/version.h.in @@ -1,4 +1,4 @@ #define BUILD_COMMIT_ID "@VERSION@" -#define PROJECT_VERSION "0.8.4" -#define PROJECT_VERSION_BUILD_NO "289" +#define PROJECT_VERSION "0.8.5" +#define PROJECT_VERSION_BUILD_NO "294" #define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")" |