Merge pull request #686
7db89ed
ARMv7: fix unaligned accesses (Howard Chu)5a07cef
Wrap some more actions in a larger read txn (Howard Chu)8cc7a36
read txn/cursor stuff (Howard Chu)86a7f2b
core: check whether an update is needed straight away (moneromooo-monero)ea5fa5e
core: print "update needed" hard fork notifications in red (moneromooo-monero)
This commit is contained in:
commit
d60bf4ee36
8 changed files with 379 additions and 197 deletions
|
@ -1837,7 +1837,7 @@ void BlockchainBDB::set_batch_transactions(bool batch_transactions)
|
|||
LOG_PRINT_L3("batch transactions " << (m_batch_transactions ? "enabled" : "disabled"));
|
||||
}
|
||||
|
||||
void BlockchainBDB::block_txn_start()
|
||||
void BlockchainBDB::block_txn_start(bool readonly)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
|
@ -329,7 +329,7 @@ public:
|
|||
virtual void batch_stop();
|
||||
virtual void batch_abort();
|
||||
|
||||
virtual void block_txn_start();
|
||||
virtual void block_txn_start(bool readonly);
|
||||
virtual void block_txn_stop();
|
||||
virtual void block_txn_abort();
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ uint64_t BlockchainDB::add_block( const block& blk
|
|||
, const std::vector<transaction>& txs
|
||||
)
|
||||
{
|
||||
block_txn_start();
|
||||
block_txn_start(false);
|
||||
|
||||
TIME_MEASURE_START(time1);
|
||||
crypto::hash blk_hash = get_block_hash(blk);
|
||||
|
@ -227,6 +227,9 @@ void BlockchainDB::fixup()
|
|||
static const char * const mainnet_genesis_hex = "418015bb9ae982a1975da7d79277c2705727a56894ba0fb246adaabb1f4632e3";
|
||||
crypto::hash mainnet_genesis_hash;
|
||||
epee::string_tools::hex_to_pod(mainnet_genesis_hex, mainnet_genesis_hash );
|
||||
set_batch_transactions(true);
|
||||
batch_start();
|
||||
|
||||
if (get_block_hash_from_height(0) == mainnet_genesis_hash)
|
||||
{
|
||||
// block 202612 (511 key images in 511 transactions)
|
||||
|
@ -762,9 +765,6 @@ void BlockchainDB::fixup()
|
|||
"633cdedeb3b96ec4f234c670254c6f721e0b368d00b48c6b26759db7d62cf52d",
|
||||
};
|
||||
|
||||
set_batch_transactions(true);
|
||||
batch_start();
|
||||
|
||||
if (height() > 202612)
|
||||
{
|
||||
for (const auto &kis: key_images_202612)
|
||||
|
@ -791,9 +791,8 @@ void BlockchainDB::fixup()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
batch_stop();
|
||||
}
|
||||
batch_stop();
|
||||
}
|
||||
|
||||
} // namespace cryptonote
|
||||
|
|
|
@ -381,7 +381,7 @@ public:
|
|||
virtual void batch_stop() = 0;
|
||||
virtual void set_batch_transactions(bool) = 0;
|
||||
|
||||
virtual void block_txn_start() = 0;
|
||||
virtual void block_txn_start(bool readonly=false) = 0;
|
||||
virtual void block_txn_stop() = 0;
|
||||
virtual void block_txn_abort() = 0;
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -30,6 +30,7 @@
|
|||
|
||||
#include "blockchain_db/blockchain_db.h"
|
||||
#include "cryptonote_protocol/blobdatatype.h" // for type blobdata
|
||||
#include <boost/thread/tss.hpp>
|
||||
|
||||
#include <lmdb.h>
|
||||
|
||||
|
@ -38,7 +39,7 @@
|
|||
namespace cryptonote
|
||||
{
|
||||
|
||||
struct mdb_txn_cursors
|
||||
typedef struct mdb_txn_cursors
|
||||
{
|
||||
MDB_cursor *m_txc_blocks;
|
||||
MDB_cursor *m_txc_block_heights;
|
||||
|
@ -59,24 +60,58 @@ struct mdb_txn_cursors
|
|||
MDB_cursor *m_txc_tx_outputs;
|
||||
|
||||
MDB_cursor *m_txc_spent_keys;
|
||||
};
|
||||
|
||||
#define m_cur_blocks m_cursors.m_txc_blocks
|
||||
#define m_cur_block_heights m_cursors.m_txc_block_heights
|
||||
#define m_cur_block_hashes m_cursors.m_txc_block_hashes
|
||||
#define m_cur_block_timestamps m_cursors.m_txc_block_timestamps
|
||||
#define m_cur_block_sizes m_cursors.m_txc_block_sizes
|
||||
#define m_cur_block_diffs m_cursors.m_txc_block_diffs
|
||||
#define m_cur_block_coins m_cursors.m_txc_block_coins
|
||||
#define m_cur_output_txs m_cursors.m_txc_output_txs
|
||||
#define m_cur_output_indices m_cursors.m_txc_output_indices
|
||||
#define m_cur_output_amounts m_cursors.m_txc_output_amounts
|
||||
#define m_cur_output_keys m_cursors.m_txc_output_keys
|
||||
#define m_cur_txs m_cursors.m_txc_txs
|
||||
#define m_cur_tx_heights m_cursors.m_txc_tx_heights
|
||||
#define m_cur_tx_unlocks m_cursors.m_txc_tx_unlocks
|
||||
#define m_cur_tx_outputs m_cursors.m_txc_tx_outputs
|
||||
#define m_cur_spent_keys m_cursors.m_txc_spent_keys
|
||||
MDB_cursor *m_txc_hf_versions;
|
||||
} mdb_txn_cursors;
|
||||
|
||||
#define m_cur_blocks m_cursors->m_txc_blocks
|
||||
#define m_cur_block_heights m_cursors->m_txc_block_heights
|
||||
#define m_cur_block_hashes m_cursors->m_txc_block_hashes
|
||||
#define m_cur_block_timestamps m_cursors->m_txc_block_timestamps
|
||||
#define m_cur_block_sizes m_cursors->m_txc_block_sizes
|
||||
#define m_cur_block_diffs m_cursors->m_txc_block_diffs
|
||||
#define m_cur_block_coins m_cursors->m_txc_block_coins
|
||||
#define m_cur_output_txs m_cursors->m_txc_output_txs
|
||||
#define m_cur_output_indices m_cursors->m_txc_output_indices
|
||||
#define m_cur_output_amounts m_cursors->m_txc_output_amounts
|
||||
#define m_cur_output_keys m_cursors->m_txc_output_keys
|
||||
#define m_cur_txs m_cursors->m_txc_txs
|
||||
#define m_cur_tx_heights m_cursors->m_txc_tx_heights
|
||||
#define m_cur_tx_unlocks m_cursors->m_txc_tx_unlocks
|
||||
#define m_cur_tx_outputs m_cursors->m_txc_tx_outputs
|
||||
#define m_cur_spent_keys m_cursors->m_txc_spent_keys
|
||||
#define m_cur_hf_versions m_cursors->m_txc_hf_versions
|
||||
|
||||
typedef struct mdb_rflags
|
||||
{
|
||||
bool m_rf_txn;
|
||||
bool m_rf_blocks;
|
||||
bool m_rf_block_heights;
|
||||
bool m_rf_block_hashes;
|
||||
bool m_rf_block_timestamps;
|
||||
bool m_rf_block_sizes;
|
||||
bool m_rf_block_diffs;
|
||||
bool m_rf_block_coins;
|
||||
bool m_rf_output_txs;
|
||||
bool m_rf_output_indices;
|
||||
bool m_rf_output_amounts;
|
||||
bool m_rf_output_keys;
|
||||
bool m_rf_txs;
|
||||
bool m_rf_tx_heights;
|
||||
bool m_rf_tx_unlocks;
|
||||
bool m_rf_tx_outputs;
|
||||
bool m_rf_spent_keys;
|
||||
bool m_rf_hf_versions;
|
||||
} mdb_rflags;
|
||||
|
||||
typedef struct mdb_threadinfo
|
||||
{
|
||||
MDB_txn *m_ti_rtxn; // per-thread read txn
|
||||
mdb_txn_cursors m_ti_rcursors; // per-thread read cursors
|
||||
mdb_rflags m_ti_rflags; // per-thread read state
|
||||
|
||||
~mdb_threadinfo();
|
||||
} mdb_threadinfo;
|
||||
|
||||
struct mdb_txn_safe
|
||||
{
|
||||
|
@ -234,9 +269,11 @@ public:
|
|||
virtual void batch_stop();
|
||||
virtual void batch_abort();
|
||||
|
||||
virtual void block_txn_start();
|
||||
virtual void block_txn_start(bool readonly);
|
||||
virtual void block_txn_stop();
|
||||
virtual void block_txn_abort();
|
||||
virtual bool block_rtxn_start() const;
|
||||
virtual void block_rtxn_stop() const;
|
||||
|
||||
virtual void pop_block(block& blk, std::vector<transaction>& txs);
|
||||
|
||||
|
@ -355,7 +392,8 @@ private:
|
|||
bool m_batch_transactions; // support for batch transactions
|
||||
bool m_batch_active; // whether batch transaction is in progress
|
||||
|
||||
struct mdb_txn_cursors m_cursors;
|
||||
mdb_txn_cursors m_wcursors;
|
||||
mutable boost::thread_specific_ptr<mdb_threadinfo> m_tinfo;
|
||||
|
||||
#if defined(__arm__)
|
||||
// force a value so it can compile with 32-bit ARM
|
||||
|
|
|
@ -334,6 +334,7 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const cryptonote::te
|
|||
m_db->fixup();
|
||||
}
|
||||
|
||||
m_db->block_txn_start(true);
|
||||
// check how far behind we are
|
||||
uint64_t top_block_timestamp = m_db->get_top_block_timestamp();
|
||||
uint64_t timestamp_diff = time(NULL) - top_block_timestamp;
|
||||
|
@ -354,6 +355,7 @@ bool Blockchain::init(BlockchainDB* db, const bool testnet, const cryptonote::te
|
|||
#endif
|
||||
|
||||
LOG_PRINT_GREEN("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block(), LOG_LEVEL_0);
|
||||
m_db->block_txn_stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -549,6 +551,7 @@ bool Blockchain::get_short_chain_history(std::list<crypto::hash>& ids) const
|
|||
if(!sz)
|
||||
return true;
|
||||
|
||||
m_db->block_txn_start(true);
|
||||
bool genesis_included = false;
|
||||
uint64_t current_back_offset = 1;
|
||||
while(current_back_offset < sz)
|
||||
|
@ -575,6 +578,7 @@ bool Blockchain::get_short_chain_history(std::list<crypto::hash>& ids) const
|
|||
{
|
||||
ids.push_back(m_db->get_block_hash_from_height(0));
|
||||
}
|
||||
m_db->block_txn_stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -996,12 +1000,14 @@ void Blockchain::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count)
|
|||
if(h == 0)
|
||||
return;
|
||||
|
||||
m_db->block_txn_start(true);
|
||||
// add size of last <count> blocks to vector <sz> (or less, if blockchain size < count)
|
||||
size_t start_offset = h - std::min<size_t>(h, count);
|
||||
for(size_t i = start_offset; i < h; i++)
|
||||
{
|
||||
sz.push_back(m_db->get_block_size(i));
|
||||
}
|
||||
m_db->block_txn_stop();
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
uint64_t Blockchain::get_current_cumulative_blocksize_limit() const
|
||||
|
@ -1403,6 +1409,7 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
|
|||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
m_db->block_txn_start(true);
|
||||
rsp.current_blockchain_height = get_current_blockchain_height();
|
||||
std::list<block> blocks;
|
||||
get_blocks(arg.blocks, blocks, rsp.missed_ids);
|
||||
|
@ -1424,6 +1431,7 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
|
|||
// as done below if any standalone transactions were requested
|
||||
// and missed.
|
||||
rsp.missed_ids.splice(rsp.missed_ids.end(), missed_tx_ids);
|
||||
m_db->block_txn_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1442,6 +1450,7 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
|
|||
for (const auto& tx: txs)
|
||||
rsp.txs.push_back(t_serializable_object_to_blob(tx));
|
||||
|
||||
m_db->block_txn_stop();
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
@ -1585,12 +1594,14 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
|
|||
return false;
|
||||
}
|
||||
|
||||
m_db->block_txn_start(true);
|
||||
// make sure that the last block in the request's block list matches
|
||||
// the genesis block
|
||||
auto gen_hash = m_db->get_block_hash_from_height(0);
|
||||
if(qblock_ids.back() != gen_hash)
|
||||
{
|
||||
LOG_PRINT_L1("Client sent wrong NOTIFY_REQUEST_CHAIN: genesis block missmatch: " << std::endl << "id: " << qblock_ids.back() << ", " << std::endl << "expected: " << gen_hash << "," << std::endl << " dropping connection");
|
||||
m_db->block_txn_abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1612,9 +1623,11 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
|
|||
catch (const std::exception& e)
|
||||
{
|
||||
LOG_PRINT_L1("Non-critical error trying to find block by hash in BlockchainDB, hash: " << *bl_it);
|
||||
m_db->block_txn_abort();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_db->block_txn_stop();
|
||||
|
||||
// this should be impossible, as we checked that we share the genesis block,
|
||||
// but just in case...
|
||||
|
@ -2427,9 +2440,12 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
TIME_MEASURE_START(t1);
|
||||
|
||||
m_db->block_txn_start(true);
|
||||
if(bl.prev_id != get_tail_id())
|
||||
{
|
||||
LOG_PRINT_L1("Block with id: " << id << std::endl << "has wrong prev_id: " << bl.prev_id << std::endl << "expected: " << get_tail_id());
|
||||
leave:
|
||||
m_db->block_txn_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2438,7 +2454,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
{
|
||||
LOG_PRINT_L1("Block with id: " << id << std::endl << "has old version: " << (unsigned)bl.major_version << std::endl << "current: " << (unsigned)m_hardfork->get_current_version());
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
TIME_MEASURE_FINISH(t1);
|
||||
|
@ -2450,7 +2466,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
{
|
||||
LOG_PRINT_L1("Block with id: " << id << std::endl << "has invalid timestamp: " << bl.timestamp);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
TIME_MEASURE_FINISH(t2);
|
||||
|
@ -2490,7 +2506,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
{
|
||||
LOG_PRINT_L1("Block with id is INVALID: " << id);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
fast_check = true;
|
||||
}
|
||||
|
@ -2511,7 +2527,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
{
|
||||
LOG_PRINT_L1("Block with id: " << id << std::endl << "does not have enough proof of work: " << proof_of_work << std::endl << "unexpected difficulty: " << current_diffic);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2523,7 +2539,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
{
|
||||
LOG_ERROR("CHECKPOINT VALIDATION FAILED");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2538,7 +2554,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
{
|
||||
LOG_PRINT_L1("Block with id: " << id << " failed to pass prevalidation");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
size_t coinbase_blob_size = get_object_blobsize(bl.miner_tx);
|
||||
|
@ -2574,7 +2590,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
LOG_PRINT_L1("Block with id: " << id << " attempting to add transaction already in blockchain with id: " << tx_id);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return_tx_to_pool(txs);
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
TIME_MEASURE_FINISH(aa);
|
||||
|
@ -2587,7 +2603,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
LOG_PRINT_L1("Block with id: " << id << " has at least one unknown transaction with id: " << tx_id);
|
||||
bvc.m_verifivation_failed = true;
|
||||
return_tx_to_pool(txs);
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
TIME_MEASURE_FINISH(bb);
|
||||
|
@ -2624,7 +2640,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
LOG_PRINT_L1("Block with id " << id << " added as invalid because of wrong inputs in transactions");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return_tx_to_pool(txs);
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
|
@ -2640,7 +2656,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
LOG_PRINT_L1("Block with id " << id << " added as invalid because of wrong inputs in transactions");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return_tx_to_pool(txs);
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -2660,7 +2676,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
LOG_PRINT_L1("Block with id: " << id << " has incorrect miner transaction");
|
||||
bvc.m_verifivation_failed = true;
|
||||
return_tx_to_pool(txs);
|
||||
return false;
|
||||
goto leave;
|
||||
}
|
||||
|
||||
TIME_MEASURE_FINISH(vmt);
|
||||
|
@ -2678,6 +2694,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash&
|
|||
if(precomputed)
|
||||
block_processing_time += m_fake_pow_calc_time;
|
||||
|
||||
m_db->block_txn_stop();
|
||||
TIME_MEASURE_START(addblock);
|
||||
uint64_t new_height = 0;
|
||||
if (!bvc.m_verifivation_failed)
|
||||
|
@ -2754,10 +2771,12 @@ bool Blockchain::add_new_block(const block& bl_, block_verification_context& bvc
|
|||
crypto::hash id = get_block_hash(bl);
|
||||
CRITICAL_REGION_LOCAL(m_tx_pool);//to avoid deadlock lets lock tx_pool for whole add/reorganize process
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
|
||||
m_db->block_txn_start(true);
|
||||
if(have_block(id))
|
||||
{
|
||||
LOG_PRINT_L3("block with id = " << id << " already exists");
|
||||
bvc.m_already_exists = true;
|
||||
m_db->block_txn_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -2766,10 +2785,12 @@ bool Blockchain::add_new_block(const block& bl_, block_verification_context& bvc
|
|||
{
|
||||
//chain switching or wrong block
|
||||
bvc.m_added_to_main_chain = false;
|
||||
m_db->block_txn_stop();
|
||||
return handle_alternative_block(bl, id, bvc);
|
||||
//never relay alternative blocks
|
||||
}
|
||||
|
||||
m_db->block_txn_stop();
|
||||
return handle_block_to_main_chain(bl, id, bvc);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
|
@ -2777,6 +2798,7 @@ void Blockchain::check_against_checkpoints(const checkpoints& points, bool enfor
|
|||
{
|
||||
const auto& pts = points.get_points();
|
||||
|
||||
m_db->batch_start();
|
||||
for (const auto& pt : pts)
|
||||
{
|
||||
// if the checkpoint is for a block we don't have yet, move on
|
||||
|
@ -2800,6 +2822,7 @@ void Blockchain::check_against_checkpoints(const checkpoints& points, bool enfor
|
|||
}
|
||||
}
|
||||
}
|
||||
m_db->batch_stop();
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// returns false if any of the checkpoints loading returns false.
|
||||
|
|
|
@ -254,8 +254,11 @@ bool HardFork::reorganize_from_chain_height(uint64_t height)
|
|||
bool HardFork::rescan_from_block_height(uint64_t height)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(lock);
|
||||
if (height >= db.height())
|
||||
db.block_txn_start(true);
|
||||
if (height >= db.height()) {
|
||||
db.block_txn_stop();
|
||||
return false;
|
||||
}
|
||||
|
||||
versions.clear();
|
||||
|
||||
|
@ -273,6 +276,7 @@ bool HardFork::rescan_from_block_height(uint64_t height)
|
|||
current_fork_index = 0;
|
||||
while (current_fork_index + 1 < heights.size() && heights[current_fork_index].version != lastv)
|
||||
++current_fork_index;
|
||||
db.block_txn_stop();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue