aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAntonio Juarez <antonio.maria.juarez@live.com>2014-04-09 13:14:35 +0100
committerAntonio Juarez <antonio.maria.juarez@live.com>2014-04-09 13:14:35 +0100
commit9682a15400495ae490543e7e5af242ff5c4c9fa0 (patch)
tree63ba7287d8f679742a244413291d4334fc26b6e6 /src
parentImprovements in JSON RPC (diff)
downloadmonero-9682a15400495ae490543e7e5af242ff5c4c9fa0.tar.xz
Port mapping with UPnP
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt10
-rw-r--r--src/cryptonote_core/checkpoints_create.h3
-rw-r--r--src/p2p/net_node.inl35
-rw-r--r--src/rpc/core_rpc_server.cpp139
-rw-r--r--src/rpc/core_rpc_server.h20
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h93
-rw-r--r--src/version.h.in4
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 ")"