Skip to content

Commit

Permalink
Optimize first initialization of stakes storage and blockchain based …
Browse files Browse the repository at this point in the history
…list
  • Loading branch information
LenyKholodov committed Mar 18, 2019
1 parent c9de8b7 commit 0114f7b
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 47 deletions.
5 changes: 5 additions & 0 deletions src/cryptonote_core/blockchain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4194,6 +4194,11 @@ bool Blockchain::get_hard_fork_voting_info(uint8_t version, uint32_t &window, ui
return m_hardfork->get_voting_info(version, window, votes, threshold, earliest_height, voting);
}

uint64_t Blockchain::get_earliest_ideal_height_for_version(uint8_t version) const
{
return m_hardfork->get_earliest_ideal_height_for_version(version);
}

std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> Blockchain:: get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff) const
{
return m_db->get_output_histogram(amounts, unlocked, recent_cutoff);
Expand Down
5 changes: 5 additions & 0 deletions src/cryptonote_core/blockchain.h
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,11 @@ namespace cryptonote
*/
bool get_hard_fork_voting_info(uint8_t version, uint32_t &window, uint32_t &votes, uint32_t &threshold, uint64_t &earliest_height, uint8_t &voting) const;

/**
* @brief returns the earliest block a given version may activate
*/
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const;

/**
* @brief remove transactions from the transaction pool (if present)
*
Expand Down
9 changes: 5 additions & 4 deletions src/cryptonote_core/blockchain_based_list.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,11 @@ const size_t BLOCKCHAIN_BASED_LISTS_HISTORY_DEPTH = 1000;

}

BlockchainBasedList::BlockchainBasedList(const std::string& m_storage_file_name)
BlockchainBasedList::BlockchainBasedList(const std::string& m_storage_file_name, uint64_t first_block_number)
: m_storage_file_name(m_storage_file_name)
, m_block_height()
, m_block_height(first_block_number)
, m_history_depth()
, m_first_block_number(first_block_number)
, m_need_store()
{
load();
Expand Down Expand Up @@ -186,7 +187,7 @@ void BlockchainBasedList::apply_block(uint64_t block_height, const crypto::hash&

void BlockchainBasedList::remove_latest_block()
{
if (!m_block_height)
if (!m_history_depth)
return;

m_need_store = true;
Expand All @@ -197,7 +198,7 @@ void BlockchainBasedList::remove_latest_block()
m_history.pop_back();

if (m_history.empty())
m_block_height = 0;
m_block_height = m_first_block_number;
}

namespace
Expand Down
3 changes: 2 additions & 1 deletion src/cryptonote_core/blockchain_based_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class BlockchainBasedList
typedef std::list<supernode_tier_array> list_history;

/// Constructors
BlockchainBasedList(const std::string& file_name);
BlockchainBasedList(const std::string& file_name, uint64_t first_block_number);

/// List of tiers
const supernode_tier_array& tiers(size_t depth = 0) const;
Expand Down Expand Up @@ -69,6 +69,7 @@ class BlockchainBasedList
uint64_t m_block_height;
size_t m_history_depth;
std::mt19937_64 m_rng;
uint64_t m_first_block_number;
mutable bool m_need_store;
};

Expand Down
82 changes: 50 additions & 32 deletions src/cryptonote_core/stake_transaction_processor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,29 @@ uint64_t get_transaction_amount(const transaction& tx, const account_public_addr
}

void StakeTransactionProcessor::init_storages(const std::string& config_dir)
{
CRITICAL_REGION_LOCAL1(m_storage_lock);

if (m_storage || m_blockchain_based_list)
throw std::runtime_error("StakeTransactionProcessor storages have been already initialized");

m_config_dir = config_dir;
}

void StakeTransactionProcessor::init_storages_impl()
{
if (m_storage || m_blockchain_based_list)
throw std::runtime_error("StakeTransactionProcessor storages have been already initialized");

m_storage.reset(new StakeTransactionStorage(config_dir + "/" + STAKE_TRANSACTION_STORAGE_FILE_NAME));
m_blockchain_based_list.reset(new BlockchainBasedList(config_dir + "/" + BLOCKCHAIN_BASED_LIST_FILE_NAME));
uint64_t first_block_number = m_blockchain.get_earliest_ideal_height_for_version(config::graft::STAKE_TRANSACTION_PROCESSING_DB_VERSION);

if (first_block_number)
first_block_number--;

MCLOG(el::Level::Info, "global", "Initialize stake processing storages. First block height is " << first_block_number);

m_storage.reset(new StakeTransactionStorage(m_config_dir + "/" + STAKE_TRANSACTION_STORAGE_FILE_NAME, first_block_number));
m_blockchain_based_list.reset(new BlockchainBasedList(m_config_dir + "/" + BLOCKCHAIN_BASED_LIST_FILE_NAME, first_block_number));
}

void StakeTransactionProcessor::process_block_stake_transaction(uint64_t block_index, const block& block, const crypto::hash& block_hash, bool update_storage)
Expand Down Expand Up @@ -248,24 +265,27 @@ void StakeTransactionProcessor::synchronize()
{
CRITICAL_REGION_LOCAL1(m_storage_lock);

if (!m_storage || !m_blockchain_based_list)
throw std::runtime_error("StakeTransactionProcessor storages have not been initialized");

BlockchainDB& db = m_blockchain.get_db();

uint64_t height = db.height();

if (!height || m_blockchain.get_hard_fork_version(height - 1) < config::graft::STAKE_TRANSACTION_PROCESSING_DB_VERSION)
return;

if (!m_storage || !m_blockchain_based_list)
{
init_storages_impl();
}

//unroll already processed blocks for alternative chains

try {
uint64_t height = db.height();

for (;;)
try
{
while (m_storage->has_last_processed_block())
{
size_t stake_tx_count = m_storage->get_tx_count();
uint64_t last_processed_block_index = m_storage->get_last_processed_block_index();

if (!last_processed_block_index)
break;

if (last_processed_block_index < height)
{
try
Expand Down Expand Up @@ -301,24 +321,19 @@ void StakeTransactionProcessor::synchronize()
if (first_block_index > m_blockchain_based_list->block_height() + 1)
first_block_index = m_blockchain_based_list->block_height() + 1;

static const uint64_t SYNC_DEBUG_LOG_STEP = 10000;
static const uint64_t SYNC_DEBUG_LOG_STEP = 10000;
static const uint64_t MAX_ITERATIONS_COUNT = 10000;

bool need_finalize_log_messages = false;
uint64_t last_block_index = first_block_index,
last_block_index_for_sync = height;

uint64_t last_block_index = first_block_index;
if (last_block_index_for_sync - last_block_index > MAX_ITERATIONS_COUNT)
last_block_index_for_sync = first_block_index + MAX_ITERATIONS_COUNT;

for (uint64_t sync_debug_log_next_index=first_block_index + 1; last_block_index<height; last_block_index++)
for (; last_block_index<last_block_index_for_sync; last_block_index++)
{
if (last_block_index == sync_debug_log_next_index)
{
MCLOG(el::Level::Info, "global", "RTA block sync " << last_block_index << "/" << height);

need_finalize_log_messages = true;
sync_debug_log_next_index = last_block_index + SYNC_DEBUG_LOG_STEP;

if (sync_debug_log_next_index >= height)
sync_debug_log_next_index = height - 1;
}
if (last_block_index % SYNC_DEBUG_LOG_STEP == 0 || last_block_index == height - 1)
MCLOG(el::Level::Info, "global", "RTA block sync " << last_block_index << "/" << (height - 1));

try
{
Expand All @@ -340,14 +355,17 @@ void StakeTransactionProcessor::synchronize()
if (m_storage->need_store())
m_storage->store();

if (m_stakes_need_update && m_on_stakes_update)
invoke_update_stakes_handler_impl(last_block_index - 1);
if (last_block_index == height)
{
if (m_stakes_need_update && m_on_stakes_update)
invoke_update_stakes_handler_impl(last_block_index - 1);

if (m_blockchain_based_list_need_update && m_on_blockchain_based_list_update)
invoke_update_blockchain_based_list_handler_impl(last_block_index - first_block_index);
if (m_blockchain_based_list_need_update && m_on_blockchain_based_list_update)
invoke_update_blockchain_based_list_handler_impl(last_block_index - first_block_index);

if (need_finalize_log_messages)
MCLOG(el::Level::Info, "global", "Stake transactions sync OK");
if (first_block_index != last_block_index)
MCLOG(el::Level::Info, "global", "Stake transactions sync OK");
}
}
catch (const std::exception &e)
{
Expand Down
2 changes: 2 additions & 0 deletions src/cryptonote_core/stake_transaction_processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,15 @@ class StakeTransactionProcessor
void invoke_update_blockchain_based_list_handler(bool force = true, size_t depth = 1);

private:
void init_storages_impl();
void process_block(uint64_t block_index, const block& block, const crypto::hash& block_hash, bool update_storage = true);
void invoke_update_stakes_handler_impl(uint64_t block_index);
void invoke_update_blockchain_based_list_handler_impl(size_t depth);
void process_block_stake_transaction(uint64_t block_index, const block& block, const crypto::hash& block_hash, bool update_storage = true);
void process_block_blockchain_based_list(uint64_t block_index, const block& block, const crypto::hash& block_hash, bool update_storage = true);

private:
std::string m_config_dir;
Blockchain& m_blockchain;
std::unique_ptr<StakeTransactionStorage> m_storage;
std::unique_ptr<BlockchainBasedList> m_blockchain_based_list;
Expand Down
19 changes: 10 additions & 9 deletions src/cryptonote_core/stake_transaction_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,13 @@ struct stake_transaction_file_data

}

StakeTransactionStorage::StakeTransactionStorage(const std::string& storage_file_name)
StakeTransactionStorage::StakeTransactionStorage(const std::string& storage_file_name, uint64_t first_block_number)
: m_storage_file_name(storage_file_name)
, m_last_processed_block_index()
, m_last_processed_block_index(first_block_number)
, m_last_processed_block_hashes_count()
, m_need_store()
, m_supernode_stakes_update_block_number()
, m_first_block_number(first_block_number)
{
load();
}
Expand Down Expand Up @@ -87,7 +88,7 @@ void StakeTransactionStorage::add_last_processed_block(uint64_t index, const cry

void StakeTransactionStorage::remove_last_processed_block()
{
if (!m_last_processed_block_index)
if (!m_last_processed_block_hashes_count)
return;

m_need_store = true;
Expand All @@ -107,7 +108,7 @@ void StakeTransactionStorage::remove_last_processed_block()

m_stake_txs.clear();

m_last_processed_block_index = 0;
m_last_processed_block_index = m_first_block_number;
}
}

Expand Down Expand Up @@ -144,7 +145,7 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number)
if (block_number == m_supernode_stakes_update_block_number)
return;

MDEBUG("Build stakes for block " << block_number);
MCLOG(el::Level::Info, "global", "Build stakes for block " << block_number);

m_supernode_stakes.clear();
m_supernode_stake_indexes.clear();
Expand All @@ -169,7 +170,7 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number)
obsolete_stake = true;
}

MDEBUG("...use stake transaction " << tx.hash << " as " << (obsolete_stake ? "obsolete" : "normal") << " stake transaction ");
MCLOG(el::Level::Info, "global", "...use stake transaction " << tx.hash << " as " << (obsolete_stake ? "obsolete" : "normal") << " stake transaction ");

//compute stake validity period

Expand Down Expand Up @@ -200,7 +201,7 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number)
new_stake.block_height = min_tx_block_height;
new_stake.unlock_time = max_tx_block_height - min_tx_block_height;

MDEBUG("...first stake transaction for supernode " << tx.supernode_public_id << ": amount=" << tx.amount << ", tier=" <<
MCLOG(el::Level::Info, "global", "...first stake transaction for supernode " << tx.supernode_public_id << ": amount=" << tx.amount << ", tier=" <<
new_stake.tier << ", validity=[" << min_tx_block_height << ";" << max_tx_block_height << ")");
}

Expand All @@ -219,7 +220,7 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number)
if (obsolete_stake)
continue; //no need to aggregate fields from obsolete stake

MDEBUG("...accumulate stake transaction for supernode " << tx.supernode_public_id << ": amount=" << tx.amount <<
MCLOG(el::Level::Info, "global", "...accumulate stake transaction for supernode " << tx.supernode_public_id << ": amount=" << tx.amount <<
", validity=[" << min_tx_block_height << ";" << max_tx_block_height << ")");

supernode_stake& stake = m_supernode_stakes[it->second];
Expand Down Expand Up @@ -258,7 +259,7 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number)
stake.block_height = min_block_height;
stake.unlock_time = max_block_height - min_block_height;

MDEBUG("...stake for supernode " << tx.supernode_public_id << ": amount=" << stake.amount << ", tier=" << stake.tier <<
MCLOG(el::Level::Info, "global", "...stake for supernode " << tx.supernode_public_id << ": amount=" << stake.amount << ", tier=" << stake.tier <<
", validity=[" << min_block_height << ";" << max_block_height << ")");
}
}
Expand Down
6 changes: 5 additions & 1 deletion src/cryptonote_core/stake_transaction_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class StakeTransactionStorage
typedef std::list<crypto::hash> block_hash_list;
typedef std::vector<supernode_stake> supernode_stake_array;

StakeTransactionStorage(const std::string& storage_file_name);
StakeTransactionStorage(const std::string& storage_file_name, uint64_t first_block_number);

/// Get number of transactions
size_t get_tx_count() const { return m_stake_txs.size(); }
Expand All @@ -67,6 +67,9 @@ class StakeTransactionStorage
/// Get array of last block hashes
const crypto::hash& get_last_processed_block_hash() const;

/// Has last processed blocks
bool has_last_processed_block() const { return m_last_processed_block_hashes_count > 0; }

/// Add new processed block
void add_last_processed_block(uint64_t index, const crypto::hash& hash);

Expand Down Expand Up @@ -109,6 +112,7 @@ class StakeTransactionStorage
uint64_t m_supernode_stakes_update_block_number;
supernode_stake_array m_supernode_stakes;
supernode_stake_index_map m_supernode_stake_indexes;
uint64_t m_first_block_number;
mutable bool m_need_store;
};

Expand Down

0 comments on commit 0114f7b

Please sign in to comment.