Skip to content

Commit

Permalink
Merge commit '702a410' into LokiMergeUpstream20180821
Browse files Browse the repository at this point in the history
  • Loading branch information
Doy-lee committed Sep 19, 2018
2 parents b64d704 + 702a410 commit ad8cdc1
Show file tree
Hide file tree
Showing 19 changed files with 183 additions and 111 deletions.
1 change: 0 additions & 1 deletion src/common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ loki_add_library(common
DEPENDS generate_translations_header)
target_link_libraries(common
PUBLIC
epee
cncrypto
${UNBOUND_LIBRARY}
${LIBUNWIND_LIBRARIES}
Expand Down
6 changes: 0 additions & 6 deletions src/crypto/crypto.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,12 +94,6 @@ namespace crypto {
}

/* generate a random 32-byte (256-bit) integer and copy it to res */
static inline void random_scalar_not_thread_safe(ec_scalar &res) {
unsigned char tmp[64];
generate_random_bytes_not_thread_safe(64, tmp);
sc_reduce(tmp);
memcpy(&res, tmp, 32);
}
static inline void random_scalar(ec_scalar &res) {
unsigned char tmp[64];
generate_random_bytes_thread_safe(64, tmp);
Expand Down
5 changes: 4 additions & 1 deletion src/cryptonote_core/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2286,7 +2286,8 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
CRITICAL_REGION_LOCAL(m_blockchain_lock);

bool result = find_blockchain_supplement(qblock_ids, resp.m_block_ids, resp.start_height, resp.total_height);
resp.cumulative_difficulty = m_db->get_block_cumulative_difficulty(resp.total_height - 1);
if (result)
resp.cumulative_difficulty = m_db->get_block_cumulative_difficulty(resp.total_height - 1);

return result;
}
Expand Down Expand Up @@ -3508,6 +3509,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
if(bl.prev_id != get_tail_id())
{
MERROR_VER("Block with id: " << id << std::endl << "has wrong prev_id: " << bl.prev_id << std::endl << "expected: " << get_tail_id());
bvc.m_verifivation_failed = true;
leave:
m_db->block_txn_stop();
return false;
Expand Down Expand Up @@ -3809,6 +3811,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
{
//TODO: figure out the best way to deal with this failure
LOG_ERROR("Error adding block with hash: " << id << " to blockchain, what = " << e.what());
bvc.m_verifivation_failed = true;
return_tx_to_pool(txs);
return false;
}
Expand Down
33 changes: 28 additions & 5 deletions src/cryptonote_core/tx_pool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,7 @@ namespace cryptonote
crypto::hash max_used_block_id = null_hash;
uint64_t max_used_block_height = 0;
cryptonote::txpool_tx_meta_t meta;
bool ch_inp_res = m_blockchain.check_tx_inputs(tx, max_used_block_height, max_used_block_id, tvc, kept_by_block);
bool ch_inp_res = check_tx_inputs([&tx]()->cryptonote::transaction&{ return tx; }, id, max_used_block_height, max_used_block_id, tvc, kept_by_block);
if(!ch_inp_res)
{
// if the transaction was valid before (kept_by_block), then it
Expand Down Expand Up @@ -1007,11 +1007,15 @@ namespace cryptonote
//---------------------------------------------------------------------------------
bool tx_memory_pool::on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id)
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
m_input_cache.clear();
return true;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id)
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
m_input_cache.clear();
return true;
}
//---------------------------------------------------------------------------------
Expand Down Expand Up @@ -1051,7 +1055,26 @@ namespace cryptonote
m_transactions_lock.unlock();
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::is_transaction_ready_to_go(txpool_tx_meta_t& txd, const cryptonote::blobdata &txblob, transaction &tx) const
bool tx_memory_pool::check_tx_inputs(const std::function<cryptonote::transaction&(void)> &get_tx, const crypto::hash &txid, uint64_t &max_used_block_height, crypto::hash &max_used_block_id, tx_verification_context &tvc, bool kept_by_block) const
{
if (!kept_by_block)
{
const std::unordered_map<crypto::hash, std::tuple<bool, tx_verification_context, uint64_t, crypto::hash>>::const_iterator i = m_input_cache.find(txid);
if (i != m_input_cache.end())
{
max_used_block_height = std::get<2>(i->second);
max_used_block_id = std::get<3>(i->second);
tvc = std::get<1>(i->second);
return std::get<0>(i->second);
}
}
bool ret = m_blockchain.check_tx_inputs(get_tx(), max_used_block_height, max_used_block_id, tvc, kept_by_block);
if (!kept_by_block)
m_input_cache.insert(std::make_pair(txid, std::make_tuple(ret, tvc, max_used_block_height, max_used_block_id)));
return ret;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const
{
struct transction_parser
{
Expand Down Expand Up @@ -1080,7 +1103,7 @@ namespace cryptonote
return false;//we already sure that this tx is broken for this height

tx_verification_context tvc;
if(!m_blockchain.check_tx_inputs(lazy_tx(), txd.max_used_block_height, txd.max_used_block_id, tvc))
if(!check_tx_inputs([&lazy_tx]()->cryptonote::transaction&{ return lazy_tx(); }, txid, txd.max_used_block_height, txd.max_used_block_id, tvc))
{
txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1;
txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height);
Expand All @@ -1097,7 +1120,7 @@ namespace cryptonote
return false;
//check ring signature again, it is possible (with very small chance) that this transaction become again valid
tx_verification_context tvc;
if(!m_blockchain.check_tx_inputs(lazy_tx(), txd.max_used_block_height, txd.max_used_block_id, tvc))
if(!check_tx_inputs([&lazy_tx]()->cryptonote::transaction&{ return lazy_tx(); }, txid, txd.max_used_block_height, txd.max_used_block_id, tvc))
{
txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1;
txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height);
Expand Down Expand Up @@ -1291,7 +1314,7 @@ namespace cryptonote
bool ready = false;
try
{
ready = is_transaction_ready_to_go(meta, txblob, tx);
ready = is_transaction_ready_to_go(meta, sorted_it->second, txblob, tx);
}
catch (const std::exception &e)
{
Expand Down
8 changes: 7 additions & 1 deletion src/cryptonote_core/tx_pool.h
Original file line number Diff line number Diff line change
Expand Up @@ -505,12 +505,13 @@ namespace cryptonote
* @brief check if a transaction is a valid candidate for inclusion in a block
*
* @param txd the transaction to check (and info about it)
* @param txid the txid of the transaction to check
* @param txblob the transaction blob to check
* @param tx the parsed transaction, if successful
*
* @return true if the transaction is good to go, otherwise false
*/
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const cryptonote::blobdata &txblob, transaction &tx) const;
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const;

/**
* @brief mark all transactions double spending the one passed
Expand Down Expand Up @@ -563,6 +564,9 @@ namespace cryptonote
*/
sorted_tx_container::iterator find_tx_in_sorted_container(const crypto::hash& id) const;

//! cache/call Blockchain::check_tx_inputs results
bool check_tx_inputs(const std::function<cryptonote::transaction&(void)> &get_tx, const crypto::hash &txid, uint64_t &max_used_block_height, crypto::hash &max_used_block_id, tx_verification_context &tvc, bool kept_by_block = false) const;

//! transactions which are unlikely to be included in blocks
/*! These transactions are kept in RAM in case they *are* included
* in a block eventually, but this container is not saved to disk.
Expand All @@ -573,6 +577,8 @@ namespace cryptonote

size_t m_txpool_max_size;
size_t m_txpool_size;

mutable std::unordered_map<crypto::hash, std::tuple<bool, tx_verification_context, uint64_t, crypto::hash>> m_input_cache;
};
}

Expand Down
1 change: 0 additions & 1 deletion src/daemon/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ target_link_libraries(daemon
daemonizer
serialization
daemon_rpc_server
epee
${EPEE_READLINE}
version
${Boost_CHRONO_LIBRARY}
Expand Down
1 change: 0 additions & 1 deletion src/p2p/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ source_group(p2p FILES ${P2P})
loki_add_library(p2p ${P2P})
target_link_libraries(p2p
PUBLIC
epee
version
cryptonote_core
${UPNP_LIBRARIES}
Expand Down
1 change: 0 additions & 1 deletion src/rpc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ target_link_libraries(rpc
common
cryptonote_core
cryptonote_protocol
epee
${Boost_REGEX_LIBRARY}
${Boost_THREAD_LIBRARY}
PRIVATE
Expand Down
1 change: 0 additions & 1 deletion src/simplewallet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ target_link_libraries(simplewallet
cncrypto
common
mnemonics
epee
${EPEE_READLINE}
version
${Boost_CHRONO_LIBRARY}
Expand Down
22 changes: 16 additions & 6 deletions src/simplewallet/simplewallet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2060,6 +2060,19 @@ bool simple_wallet::set_segregation_height(const std::vector<std::string> &args/
return true;
}

bool simple_wallet::set_ignore_fractional_outputs(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
const auto pwd_container = get_and_verify_password();
if (pwd_container)
{
parse_bool_and_use(args[1], [&](bool r) {
m_wallet->ignore_fractional_outputs(r);
m_wallet->rewrite(m_wallet_file, pwd_container->password());
});
}
return true;
}

bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
if(args.empty())
Expand Down Expand Up @@ -2460,6 +2473,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
const std::pair<size_t, size_t> lookahead = m_wallet->get_subaddress_lookahead();
success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second;
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs();
return true;
}
else
Expand Down Expand Up @@ -2513,6 +2527,7 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
CHECK_SIMPLE_VARIABLE("key-reuse-mitigation2", set_key_reuse_mitigation2, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("subaddress-lookahead", set_subaddress_lookahead, tr("<major>:<minor>"));
CHECK_SIMPLE_VARIABLE("segregation-height", set_segregation_height, tr("unsigned integer"));
CHECK_SIMPLE_VARIABLE("ignore-fractional-outputs", set_ignore_fractional_outputs, tr("0 or 1"));
}
fail_msg_writer() << tr("set: unrecognized argument(s)");
return true;
Expand Down Expand Up @@ -4258,12 +4273,7 @@ uint64_t simple_wallet::get_daemon_blockchain_height(std::string& err)
{
throw std::runtime_error("simple_wallet null wallet");
}

COMMAND_RPC_GET_HEIGHT::request req;
COMMAND_RPC_GET_HEIGHT::response res = boost::value_initialized<COMMAND_RPC_GET_HEIGHT::response>();
bool r = m_wallet->invoke_http_json("/getheight", req, res);
err = interpret_rpc_response(r, res.status);
return res.height;
return m_wallet->get_daemon_blockchain_height(err);
}
//----------------------------------------------------------------------------------------------------
bool simple_wallet::show_blockchain_height(const std::vector<std::string>& args)
Expand Down
1 change: 1 addition & 0 deletions src/simplewallet/simplewallet.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ namespace cryptonote
bool set_key_reuse_mitigation2(const std::vector<std::string> &args = std::vector<std::string>());
bool set_subaddress_lookahead(const std::vector<std::string> &args = std::vector<std::string>());
bool set_segregation_height(const std::vector<std::string> &args = std::vector<std::string>());
bool set_ignore_fractional_outputs(const std::vector<std::string> &args = std::vector<std::string>());
bool help(const std::vector<std::string> &args = std::vector<std::string>());
bool start_mining(const std::vector<std::string> &args);
bool stop_mining(const std::vector<std::string> &args);
Expand Down
1 change: 0 additions & 1 deletion src/wallet/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ loki_add_executable(wallet_rpc_server
target_link_libraries(wallet_rpc_server
PRIVATE
wallet
epee
rpc_base
cryptonote_core
cncrypto
Expand Down
72 changes: 36 additions & 36 deletions src/wallet/node_rpc_proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,22 @@ static const std::chrono::seconds rpc_timeout = std::chrono::minutes(3) + std::c
NodeRPCProxy::NodeRPCProxy(epee::net_utils::http::http_simple_client &http_client, boost::mutex &mutex)
: m_http_client(http_client)
, m_daemon_rpc_mutex(mutex)
, m_height(0)
, m_height_time(0)
, m_earliest_height()
, m_dynamic_per_kb_fee_estimate(0)
, m_dynamic_per_kb_fee_estimate_cached_height(0)
, m_dynamic_per_kb_fee_estimate_grace_blocks(0)
, m_rpc_version(0)
, m_target_height(0)
, m_target_height_time(0)
{}
{
invalidate();
}

void NodeRPCProxy::invalidate()
{
m_height = 0;
m_height_time = 0;
for (size_t n = 0; n < 256; ++n)
m_earliest_height[n] = 0;
m_dynamic_per_kb_fee_estimate = 0;
m_dynamic_per_kb_fee_estimate_cached_height = 0;
m_dynamic_per_kb_fee_estimate_grace_blocks = 0;
m_rpc_version = 0;
m_target_height = 0;
m_target_height_time = 0;
m_block_size_limit = 0;
m_get_info_time = 0;
}

boost::optional<std::string> NodeRPCProxy::get_rpc_version(uint32_t &rpc_version) const
Expand All @@ -84,36 +77,15 @@ boost::optional<std::string> NodeRPCProxy::get_rpc_version(uint32_t &rpc_version
return boost::optional<std::string>();
}

boost::optional<std::string> NodeRPCProxy::get_height(uint64_t &height) const
{
const time_t now = time(NULL);
if (m_height == 0 || now >= m_height_time + 30) // re-cache every 30 seconds
{
cryptonote::COMMAND_RPC_GET_HEIGHT::request req = AUTO_VAL_INIT(req);
cryptonote::COMMAND_RPC_GET_HEIGHT::response res = AUTO_VAL_INIT(res);

m_daemon_rpc_mutex.lock();
bool r = net_utils::invoke_http_json("/getheight", req, res, m_http_client, rpc_timeout);
m_daemon_rpc_mutex.unlock();
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(res.status != CORE_RPC_STATUS_BUSY, res.status, "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(res.status == CORE_RPC_STATUS_OK, res.status, "Failed to get current blockchain height");
m_height = res.height;
m_height_time = now;
}
height = m_height;
return boost::optional<std::string>();
}

void NodeRPCProxy::set_height(uint64_t h)
{
m_height = h;
}

boost::optional<std::string> NodeRPCProxy::get_target_height(uint64_t &height) const
boost::optional<std::string> NodeRPCProxy::get_info() const
{
const time_t now = time(NULL);
if (m_target_height == 0 || now >= m_target_height_time + 30) // re-cache every 30 seconds
if (now >= m_get_info_time + 30) // re-cache every 30 seconds
{
cryptonote::COMMAND_RPC_GET_INFO::request req_t = AUTO_VAL_INIT(req_t);
cryptonote::COMMAND_RPC_GET_INFO::response resp_t = AUTO_VAL_INIT(resp_t);
Expand All @@ -125,13 +97,41 @@ boost::optional<std::string> NodeRPCProxy::get_target_height(uint64_t &height) c
CHECK_AND_ASSERT_MES(r, std::string(), "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.status != CORE_RPC_STATUS_BUSY, resp_t.status, "Failed to connect to daemon");
CHECK_AND_ASSERT_MES(resp_t.status == CORE_RPC_STATUS_OK, resp_t.status, "Failed to get target blockchain height");
m_height = resp_t.height;
m_target_height = resp_t.target_height;
m_target_height_time = now;
m_block_size_limit = resp_t.block_size_limit;
m_get_info_time = now;
}
return boost::optional<std::string>();
}

boost::optional<std::string> NodeRPCProxy::get_height(uint64_t &height) const
{
auto res = get_info();
if (res)
return res;
height = m_height;
return boost::optional<std::string>();
}

boost::optional<std::string> NodeRPCProxy::get_target_height(uint64_t &height) const
{
auto res = get_info();
if (res)
return res;
height = m_target_height;
return boost::optional<std::string>();
}

boost::optional<std::string> NodeRPCProxy::get_block_size_limit(uint64_t &block_size_limit) const
{
auto res = get_info();
if (res)
return res;
block_size_limit = m_block_size_limit;
return boost::optional<std::string>();
}

boost::optional<std::string> NodeRPCProxy::get_earliest_height(uint8_t version, uint64_t &earliest_height) const
{
if (m_earliest_height[version] == 0)
Expand Down
Loading

0 comments on commit ad8cdc1

Please sign in to comment.