aboutsummaryrefslogtreecommitdiff
path: root/src/rpc
diff options
context:
space:
mode:
Diffstat (limited to 'src/rpc')
-rw-r--r--src/rpc/core_rpc_server.cpp137
-rw-r--r--src/rpc/core_rpc_server.h2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h49
-rw-r--r--src/rpc/core_rpc_server_error_codes.h1
-rw-r--r--src/rpc/daemon_handler.cpp38
-rw-r--r--src/rpc/daemon_messages.h2
-rw-r--r--src/rpc/message_data_structs.h1
-rw-r--r--src/rpc/rpc_args.cpp2
-rw-r--r--src/rpc/zmq_server.cpp4
9 files changed, 162 insertions, 74 deletions
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index e87078398..029c4ac09 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -194,6 +194,7 @@ namespace cryptonote
res.mainnet = m_nettype == MAINNET;
res.testnet = m_nettype == TESTNET;
res.stagenet = m_nettype == STAGENET;
+ res.nettype = m_nettype == MAINNET ? "mainnet" : m_nettype == TESTNET ? "testnet" : m_nettype == STAGENET ? "stagenet" : "fakechain";
res.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(res.height - 1);
res.block_size_limit = m_core.get_blockchain_storage().get_current_cumulative_blocksize_limit();
res.block_size_median = m_core.get_blockchain_storage().get_current_cumulative_blocksize_median();
@@ -226,47 +227,47 @@ namespace cryptonote
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_BLOCKS_FAST>(invoke_http_mode::BIN, "/getblocks.bin", req, res, r))
return r;
- std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > > bs;
+ std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > > bs;
- if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, req.prune, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
+ if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, req.prune, !req.no_miner_tx, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
{
res.status = "Failed";
return false;
}
size_t pruned_size = 0, unpruned_size = 0, ntxes = 0;
+ res.blocks.reserve(bs.size());
+ res.output_indices.reserve(bs.size());
for(auto& bd: bs)
{
res.blocks.resize(res.blocks.size()+1);
- res.blocks.back().block = bd.first;
- pruned_size += bd.first.size();
- unpruned_size += bd.first.size();
+ res.blocks.back().block = bd.first.first;
+ pruned_size += bd.first.first.size();
+ unpruned_size += bd.first.first.size();
res.output_indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::block_output_indices());
res.output_indices.back().indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::tx_output_indices());
- block b;
- if (!parse_and_validate_block_from_blob(bd.first, b))
+ if (!req.no_miner_tx)
{
- res.status = "Invalid block";
- return false;
- }
- bool r = m_core.get_tx_outputs_gindexs(get_transaction_hash(b.miner_tx), res.output_indices.back().indices.back().indices);
- if (!r)
- {
- res.status = "Failed";
- return false;
+ bool r = m_core.get_tx_outputs_gindexs(bd.first.second, res.output_indices.back().indices.back().indices);
+ if (!r)
+ {
+ res.status = "Failed";
+ return false;
+ }
}
- size_t txidx = 0;
ntxes += bd.second.size();
- for (std::list<cryptonote::blobdata>::iterator i = bd.second.begin(); i != bd.second.end(); ++i)
+ res.blocks.back().txs.reserve(bd.second.size());
+ res.output_indices.back().indices.reserve(bd.second.size());
+ for (std::vector<std::pair<crypto::hash, cryptonote::blobdata>>::iterator i = bd.second.begin(); i != bd.second.end(); ++i)
{
- unpruned_size += i->size();
- res.blocks.back().txs.push_back(std::move(*i));
- i->clear();
- i->shrink_to_fit();
+ unpruned_size += i->second.size();
+ res.blocks.back().txs.push_back(std::move(i->second));
+ i->second.clear();
+ i->second.shrink_to_fit();
pruned_size += res.blocks.back().txs.back().size();
res.output_indices.back().indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::tx_output_indices());
- bool r = m_core.get_tx_outputs_gindexs(b.tx_hashes[txidx++], res.output_indices.back().indices.back().indices);
+ bool r = m_core.get_tx_outputs_gindexs(i->first, res.output_indices.back().indices.back().indices);
if (!r)
{
res.status = "Failed";
@@ -286,7 +287,7 @@ namespace cryptonote
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_ALT_BLOCKS_HASHES>(invoke_http_mode::JON, "/get_alt_blocks_hashes", req, res, r))
return r;
- std::list<block> blks;
+ std::vector<block> blks;
if(!m_core.get_alternative_blocks(blks))
{
@@ -328,8 +329,8 @@ namespace cryptonote
res.status = "Error retrieving block at height " + std::to_string(height);
return true;
}
- std::list<transaction> txs;
- std::list<crypto::hash> missed_txs;
+ std::vector<transaction> txs;
+ std::vector<crypto::hash> missed_txs;
m_core.get_transactions(blk.tx_hashes, txs, missed_txs);
res.blocks.resize(res.blocks.size() + 1);
res.blocks.back().block = block_to_blob(blk);
@@ -544,8 +545,8 @@ namespace cryptonote
}
vh.push_back(*reinterpret_cast<const crypto::hash*>(b.data()));
}
- std::list<crypto::hash> missed_txs;
- std::list<transaction> txs;
+ std::vector<crypto::hash> missed_txs;
+ std::vector<transaction> txs;
bool r = m_core.get_transactions(vh, txs, missed_txs);
if(!r)
{
@@ -566,25 +567,26 @@ namespace cryptonote
if(r)
{
// sort to match original request
- std::list<transaction> sorted_txs;
+ std::vector<transaction> sorted_txs;
std::vector<tx_info>::const_iterator i;
+ unsigned txs_processed = 0;
for (const crypto::hash &h: vh)
{
if (std::find(missed_txs.begin(), missed_txs.end(), h) == missed_txs.end())
{
- if (txs.empty())
+ if (txs.size() == txs_processed)
{
res.status = "Failed: internal error - txs is empty";
return true;
}
// core returns the ones it finds in the right order
- if (get_transaction_hash(txs.front()) != h)
+ if (get_transaction_hash(txs[txs_processed]) != h)
{
res.status = "Failed: tx hash mismatch";
return true;
}
- sorted_txs.push_back(std::move(txs.front()));
- txs.pop_front();
+ sorted_txs.push_back(std::move(txs[txs_processed]));
+ ++txs_processed;
}
else if ((i = std::find_if(pool_tx_info.begin(), pool_tx_info.end(), [h](const tx_info &txi) { return epee::string_tools::pod_to_hex(h) == txi.id_hash; })) != pool_tx_info.end())
{
@@ -595,7 +597,7 @@ namespace cryptonote
return true;
}
sorted_txs.push_back(tx);
- missed_txs.remove(h);
+ missed_txs.erase(std::find(missed_txs.begin(), missed_txs.end(), h));
pool_tx_hashes.insert(h);
const std::string hash_string = epee::string_tools::pod_to_hex(h);
for (const auto &ti: pool_tx_info)
@@ -614,7 +616,7 @@ namespace cryptonote
LOG_PRINT_L2("Found " << found_in_pool << "/" << vh.size() << " transactions in the pool");
}
- std::list<std::string>::const_iterator txhi = req.txs_hashes.begin();
+ std::vector<std::string>::const_iterator txhi = req.txs_hashes.begin();
std::vector<crypto::hash>::const_iterator vhi = vh.begin();
for(auto& tx: txs)
{
@@ -1209,6 +1211,68 @@ namespace cryptonote
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool core_rpc_server::on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp)
+ {
+ PERF_TIMER(on_generateblocks);
+
+ CHECK_CORE_READY();
+
+ res.status = CORE_RPC_STATUS_OK;
+
+ if(m_core.get_nettype() != FAKECHAIN)
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_REGTEST_REQUIRED;
+ error_resp.message = "Regtest required when generating blocks";
+ return false;
+ }
+
+ COMMAND_RPC_GETBLOCKTEMPLATE::request template_req;
+ COMMAND_RPC_GETBLOCKTEMPLATE::response template_res;
+ COMMAND_RPC_SUBMITBLOCK::request submit_req;
+ COMMAND_RPC_SUBMITBLOCK::response submit_res;
+
+ template_req.reserve_size = 1;
+ template_req.wallet_address = req.wallet_address;
+ submit_req.push_back(boost::value_initialized<std::string>());
+ res.height = m_core.get_blockchain_storage().get_current_blockchain_height();
+
+ bool r;
+
+ for(size_t i = 0; i < req.amount_of_blocks; i++)
+ {
+ r = on_getblocktemplate(template_req, template_res, error_resp);
+ res.status = template_res.status;
+
+ if (!r) return false;
+
+ blobdata blockblob;
+ if(!string_tools::parse_hexstr_to_binbuff(template_res.blocktemplate_blob, blockblob))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
+ error_resp.message = "Wrong block blob";
+ return false;
+ }
+ block b = AUTO_VAL_INIT(b);
+ if(!parse_and_validate_block_from_blob(blockblob, b))
+ {
+ error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
+ error_resp.message = "Wrong block blob";
+ return false;
+ }
+ miner::find_nonce_for_given_block(b, template_res.difficulty, template_res.height);
+
+ submit_req.front() = string_tools::buff_to_hex_nodelimer(block_to_blob(b));
+ r = on_submitblock(submit_req, submit_res, error_resp);
+ res.status = submit_res.status;
+
+ if (!r) return false;
+
+ res.height = template_res.height;
+ }
+
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
uint64_t core_rpc_server::get_block_reward(const block& blk)
{
uint64_t reward = 0;
@@ -1564,6 +1628,7 @@ namespace cryptonote
res.mainnet = m_nettype == MAINNET;
res.testnet = m_nettype == TESTNET;
res.stagenet = m_nettype == STAGENET;
+ res.nettype = m_nettype == MAINNET ? "mainnet" : m_nettype == TESTNET ? "testnet" : m_nettype == STAGENET ? "stagenet" : "fakechain";
res.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(res.height - 1);
res.block_size_limit = m_core.get_blockchain_storage().get_current_cumulative_blocksize_limit();
res.block_size_median = m_core.get_blockchain_storage().get_current_cumulative_blocksize_median();
@@ -1655,10 +1720,10 @@ namespace cryptonote
PERF_TIMER(on_flush_txpool);
bool failed = false;
- std::list<crypto::hash> txids;
+ std::vector<crypto::hash> txids;
if (req.txids.empty())
{
- std::list<transaction> pool_txs;
+ std::vector<transaction> pool_txs;
bool r = m_core.get_pool_transactions(pool_txs);
if (!r)
{
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index 324f219f8..5e62bc4a8 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -129,6 +129,7 @@ namespace cryptonote
MAP_JON_RPC_WE("getblocktemplate", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE)
MAP_JON_RPC_WE("submit_block", on_submitblock, COMMAND_RPC_SUBMITBLOCK)
MAP_JON_RPC_WE("submitblock", on_submitblock, COMMAND_RPC_SUBMITBLOCK)
+ MAP_JON_RPC_WE_IF("generateblocks", on_generateblocks, COMMAND_RPC_GENERATEBLOCKS, !m_restricted)
MAP_JON_RPC_WE("get_last_block_header", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER)
MAP_JON_RPC_WE("getlastblockheader", on_get_last_block_header, COMMAND_RPC_GET_LAST_BLOCK_HEADER)
MAP_JON_RPC_WE("get_block_header_by_hash", on_get_block_header_by_hash, COMMAND_RPC_GET_BLOCK_HEADER_BY_HASH)
@@ -196,6 +197,7 @@ namespace cryptonote
bool on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp);
bool on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp);
bool on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp);
+ bool on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp);
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);
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);
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);
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 2fb7e9ea3..b05dcdfc0 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -83,10 +83,12 @@ namespace cryptonote
std::list<crypto::hash> block_ids; //*first 10 blocks id goes sequential, next goes in pow(2,n) offset, like 2, 4, 8, 16, 32, 64 and so on, and the last one is always genesis block */
uint64_t start_height;
bool prune;
+ bool no_miner_tx;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(block_ids)
KV_SERIALIZE(start_height)
KV_SERIALIZE(prune)
+ KV_SERIALIZE_OPT(no_miner_tx, false)
END_KV_SERIALIZE_MAP()
};
@@ -110,7 +112,7 @@ namespace cryptonote
struct response
{
- std::list<block_complete_entry> blocks;
+ std::vector<block_complete_entry> blocks;
uint64_t start_height;
uint64_t current_height;
std::string status;
@@ -188,7 +190,7 @@ namespace cryptonote
struct response
{
- std::list<crypto::hash> m_block_ids;
+ std::vector<crypto::hash> m_block_ids;
uint64_t start_height;
uint64_t current_height;
std::string status;
@@ -273,7 +275,7 @@ namespace cryptonote
uint64_t total_received;
uint64_t total_received_unlocked = 0; // OpenMonero only
uint64_t scanned_height;
- std::list<transaction> transactions;
+ std::vector<transaction> transactions;
uint64_t blockchain_height;
uint64_t scanned_block_height;
std::string status;
@@ -561,7 +563,7 @@ namespace cryptonote
{
struct request
{
- std::list<std::string> txs_hashes;
+ std::vector<std::string> txs_hashes;
bool decode_as_json;
bool prune;
@@ -598,11 +600,11 @@ namespace cryptonote
struct response
{
// older compatibility stuff
- std::list<std::string> txs_as_hex; //transactions blobs as hex (old compat)
- std::list<std::string> txs_as_json; //transactions decoded as json (old compat)
+ std::vector<std::string> txs_as_hex; //transactions blobs as hex (old compat)
+ std::vector<std::string> txs_as_json; //transactions decoded as json (old compat)
// in both old and new
- std::list<std::string> missed_tx; //not found transactions
+ std::vector<std::string> missed_tx; //not found transactions
// new style
std::vector<entry> txs;
@@ -953,6 +955,7 @@ namespace cryptonote
bool mainnet;
bool testnet;
bool stagenet;
+ std::string nettype;
std::string top_block_hash;
uint64_t cumulative_difficulty;
uint64_t block_size_limit;
@@ -982,6 +985,7 @@ namespace cryptonote
KV_SERIALIZE(mainnet)
KV_SERIALIZE(testnet)
KV_SERIALIZE(stagenet)
+ KV_SERIALIZE(nettype)
KV_SERIALIZE(top_block_hash)
KV_SERIALIZE(cumulative_difficulty)
KV_SERIALIZE(block_size_limit)
@@ -1149,6 +1153,31 @@ namespace cryptonote
END_KV_SERIALIZE_MAP()
};
};
+
+ struct COMMAND_RPC_GENERATEBLOCKS
+ {
+ struct request
+ {
+ uint64_t amount_of_blocks;
+ std::string wallet_address;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(amount_of_blocks)
+ KV_SERIALIZE(wallet_address)
+ END_KV_SERIALIZE_MAP()
+ };
+
+ struct response
+ {
+ uint64_t height;
+ std::string status;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(height)
+ KV_SERIALIZE(status)
+ END_KV_SERIALIZE_MAP()
+ };
+ };
struct block_header_response
{
@@ -1565,6 +1594,8 @@ namespace cryptonote
std::vector<txpool_histo> histo;
uint32_t num_double_spends;
+ txpool_stats(): bytes_total(0), bytes_min(0), bytes_max(0), bytes_med(0), fee_total(0), oldest(0), txs_total(0), num_failing(0), num_10m(0), num_not_relayed(0), histo_98pc(0), num_double_spends(0) {}
+
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(bytes_total)
KV_SERIALIZE(bytes_min)
@@ -1929,7 +1960,7 @@ namespace cryptonote
{
struct request
{
- std::list<std::string> txids;
+ std::vector<std::string> txids;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txids)
@@ -2150,7 +2181,7 @@ namespace cryptonote
{
struct request
{
- std::list<std::string> txids;
+ std::vector<std::string> txids;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txids)
diff --git a/src/rpc/core_rpc_server_error_codes.h b/src/rpc/core_rpc_server_error_codes.h
index 69caaa6a6..5a754749f 100644
--- a/src/rpc/core_rpc_server_error_codes.h
+++ b/src/rpc/core_rpc_server_error_codes.h
@@ -42,5 +42,6 @@
#define CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB_SIZE -10
#define CORE_RPC_ERROR_CODE_UNSUPPORTED_RPC -11
#define CORE_RPC_ERROR_CODE_MINING_TO_SUBADDRESS -12
+#define CORE_RPC_ERROR_CODE_REGTEST_REQUIRED -13
diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp
index 39f169cdf..55858cc2a 100644
--- a/src/rpc/daemon_handler.cpp
+++ b/src/rpc/daemon_handler.cpp
@@ -50,9 +50,9 @@ namespace rpc
void DaemonHandler::handle(const GetBlocksFast::Request& req, GetBlocksFast::Response& res)
{
- std::list<std::pair<blobdata, std::list<blobdata> > > blocks;
+ std::vector<std::pair<std::pair<blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, blobdata> > > > blocks;
- if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, blocks, res.current_height, res.start_height, req.prune, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
+ if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, blocks, res.current_height, res.start_height, req.prune, true, COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT))
{
res.status = Message::STATUS_FAILED;
res.error_details = "core::find_blockchain_supplement() returned false";
@@ -62,9 +62,6 @@ namespace rpc
res.blocks.resize(blocks.size());
res.output_indices.resize(blocks.size());
- //TODO: really need to switch uses of std::list to std::vector unless
- // it's a huge performance concern
-
auto it = blocks.begin();
uint64_t block_count = 0;
@@ -72,7 +69,7 @@ namespace rpc
{
cryptonote::rpc::block_with_transactions& bwt = res.blocks[block_count];
- if (!parse_and_validate_block_from_blob(it->first, bwt.block))
+ if (!parse_and_validate_block_from_blob(it->first.first, bwt.block))
{
res.blocks.clear();
res.output_indices.clear();
@@ -89,11 +86,11 @@ namespace rpc
res.error_details = "incorrect number of transactions retrieved for block";
return;
}
- std::list<transaction> txs;
- for (const auto& blob : it->second)
+ std::vector<transaction> txs;
+ for (const auto& p : it->second)
{
txs.resize(txs.size() + 1);
- if (!parse_and_validate_tx_from_blob(blob, txs.back()))
+ if (!parse_and_validate_tx_from_blob(p.second, txs.back()))
{
res.blocks.clear();
res.output_indices.clear();
@@ -163,10 +160,10 @@ namespace rpc
void DaemonHandler::handle(const GetTransactions::Request& req, GetTransactions::Response& res)
{
- std::list<cryptonote::transaction> found_txs;
- std::list<crypto::hash> missed_hashes;
+ std::vector<cryptonote::transaction> found_txs_vec;
+ std::vector<crypto::hash> missed_vec;
- bool r = m_core.get_transactions(req.tx_hashes, found_txs, missed_hashes);
+ bool r = m_core.get_transactions(req.tx_hashes, found_txs_vec, missed_vec);
// TODO: consider fixing core::get_transactions to not hide exceptions
if (!r)
@@ -176,20 +173,7 @@ namespace rpc
return;
}
- size_t num_found = found_txs.size();
-
- // std::list is annoying
- std::vector<cryptonote::transaction> found_txs_vec
- {
- std::make_move_iterator(std::begin(found_txs)),
- std::make_move_iterator(std::end(found_txs))
- };
-
- std::vector<crypto::hash> missed_vec
- {
- std::make_move_iterator(std::begin(missed_hashes)),
- std::make_move_iterator(std::end(missed_hashes))
- };
+ size_t num_found = found_txs_vec.size();
std::vector<uint64_t> heights(num_found);
std::vector<bool> in_pool(num_found, false);
@@ -204,7 +188,7 @@ namespace rpc
// if any missing from blockchain, check in tx pool
if (!missed_vec.empty())
{
- std::list<cryptonote::transaction> pool_txs;
+ std::vector<cryptonote::transaction> pool_txs;
m_core.get_pool_transactions(pool_txs);
diff --git a/src/rpc/daemon_messages.h b/src/rpc/daemon_messages.h
index 1495c845f..8fff369df 100644
--- a/src/rpc/daemon_messages.h
+++ b/src/rpc/daemon_messages.h
@@ -106,7 +106,7 @@ BEGIN_RPC_MESSAGE_CLASS(GetHashesFast);
RPC_MESSAGE_MEMBER(uint64_t, start_height);
END_RPC_MESSAGE_REQUEST;
BEGIN_RPC_MESSAGE_RESPONSE;
- RPC_MESSAGE_MEMBER(std::list<crypto::hash>, hashes);
+ RPC_MESSAGE_MEMBER(std::vector<crypto::hash>, hashes);
RPC_MESSAGE_MEMBER(uint64_t, start_height);
RPC_MESSAGE_MEMBER(uint64_t, current_height);
END_RPC_MESSAGE_RESPONSE;
diff --git a/src/rpc/message_data_structs.h b/src/rpc/message_data_structs.h
index 17ae9629f..fc1b2329d 100644
--- a/src/rpc/message_data_structs.h
+++ b/src/rpc/message_data_structs.h
@@ -181,6 +181,7 @@ namespace rpc
bool mainnet;
bool testnet;
bool stagenet;
+ std::string nettype;
crypto::hash top_block_hash;
uint64_t cumulative_difficulty;
uint64_t block_size_limit;
diff --git a/src/rpc/rpc_args.cpp b/src/rpc/rpc_args.cpp
index d4a6138ba..d4044d11b 100644
--- a/src/rpc/rpc_args.cpp
+++ b/src/rpc/rpc_args.cpp
@@ -102,7 +102,7 @@ namespace cryptonote
{
if (!config.login)
{
- LOG_ERROR(arg.rpc_access_control_origins.name << tr(" requires RFC server password --") << arg.rpc_login.name << tr(" cannot be empty"));
+ LOG_ERROR(arg.rpc_access_control_origins.name << tr(" requires RPC server password --") << arg.rpc_login.name << tr(" cannot be empty"));
return boost::none;
}
diff --git a/src/rpc/zmq_server.cpp b/src/rpc/zmq_server.cpp
index 3aee8c4c7..edd3e6669 100644
--- a/src/rpc/zmq_server.cpp
+++ b/src/rpc/zmq_server.cpp
@@ -104,6 +104,10 @@ bool ZmqServer::addTCPSocket(std::string address, std::string port)
rep_socket->setsockopt(ZMQ_RCVTIMEO, &DEFAULT_RPC_RECV_TIMEOUT_MS, sizeof(DEFAULT_RPC_RECV_TIMEOUT_MS));
+ if (address.empty())
+ address = "*";
+ if (port.empty())
+ port = "*";
std::string bind_address = addr_prefix + address + std::string(":") + port;
rep_socket->bind(bind_address.c_str());
}