From c9de8b7e4bd51e9371d4f818ca80b1f15f187d0b Mon Sep 17 00:00:00 2001 From: Leny Kholodov Date: Tue, 19 Mar 2019 00:10:22 +0200 Subject: [PATCH] Fix blockchain based list usage of previous blockchain based list --- src/cryptonote_core/blockchain_based_list.cpp | 45 ++++++++----------- .../stake_transaction_processor.cpp | 2 +- .../stake_transaction_storage.cpp | 33 ++++++++++---- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/src/cryptonote_core/blockchain_based_list.cpp b/src/cryptonote_core/blockchain_based_list.cpp index 747d5b59b..4fadb9e1c 100644 --- a/src/cryptonote_core/blockchain_based_list.cpp +++ b/src/cryptonote_core/blockchain_based_list.cpp @@ -39,25 +39,6 @@ const BlockchainBasedList::supernode_tier_array& BlockchainBasedList::tiers(size return *it; } -namespace -{ - -bool is_valid_stake(uint64_t block_height, uint64_t stake_block_height, uint64_t stake_unlock_time) -{ - if (block_height < stake_block_height) - return false; //stake transaction block is in future - - uint64_t stake_first_valid_block = stake_block_height, - stake_last_valid_block = stake_block_height + stake_unlock_time; - - if (stake_last_valid_block <= block_height) - return false; //stake transaction is not valid - - return true; -} - -} - void BlockchainBasedList::select_supernodes(size_t items_count, const supernode_array& src_list, supernode_array& dst_list) { size_t src_list_size = src_list.size(); @@ -98,14 +79,27 @@ void BlockchainBasedList::apply_block(uint64_t block_height, const crypto::hash& prev_supernodes.clear(); current_supernodes.clear(); - //prepare lists of valid supernodes (stake period is valid) + //prepare lists of valid supernodes for this tier if (!m_history.empty()) - prev_supernodes = m_history.back()[i]; + { + const supernode_array& full_prev_supernodes = m_history.back()[i]; + + prev_supernodes.reserve(full_prev_supernodes.size()); + + for (const supernode& sn : full_prev_supernodes) + { + const supernode_stake* stake = stake_txs_storage.find_supernode_stake(block_height, sn.supernode_public_id); + + if (!stake || !stake->amount) + continue; - prev_supernodes.erase(std::remove_if(prev_supernodes.begin(), prev_supernodes.end(), [block_height](const supernode& desc) { - return !is_valid_stake(block_height, desc.block_height, desc.unlock_time); - }), prev_supernodes.end()); + if (stake->tier != i + 1) + continue; + + prev_supernodes.push_back(sn); + } + } current_supernodes.reserve(stakes.size()); @@ -114,9 +108,6 @@ void BlockchainBasedList::apply_block(uint64_t block_height, const crypto::hash& if (!stake.amount) continue; - if (!is_valid_stake(block_height, stake.block_height, stake.unlock_time)) - continue; - if (stake.tier != i + 1) continue; diff --git a/src/cryptonote_core/stake_transaction_processor.cpp b/src/cryptonote_core/stake_transaction_processor.cpp index 5de682c1c..b75e9ef56 100644 --- a/src/cryptonote_core/stake_transaction_processor.cpp +++ b/src/cryptonote_core/stake_transaction_processor.cpp @@ -9,7 +9,7 @@ namespace { const char* STAKE_TRANSACTION_STORAGE_FILE_NAME = "stake_transactions.v2.bin"; -const char* BLOCKCHAIN_BASED_LIST_FILE_NAME = "blockchain_based_list.v4.bin"; +const char* BLOCKCHAIN_BASED_LIST_FILE_NAME = "blockchain_based_list.v5.bin"; } diff --git a/src/cryptonote_core/stake_transaction_storage.cpp b/src/cryptonote_core/stake_transaction_storage.cpp index c3ea2c4d8..f10047fd3 100644 --- a/src/cryptonote_core/stake_transaction_storage.cpp +++ b/src/cryptonote_core/stake_transaction_storage.cpp @@ -1,3 +1,4 @@ +#include "blockchain.h" #include "stake_transaction_storage.h" #include "file_io_utils.h" #include "serialization/binary_utils.h" @@ -143,6 +144,8 @@ 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); + m_supernode_stakes.clear(); m_supernode_stake_indexes.clear(); @@ -166,6 +169,13 @@ 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 "); + + //compute stake validity period + + uint64_t min_tx_block_height = tx.block_height + config::graft::STAKE_VALIDATION_PERIOD, + max_tx_block_height = tx.block_height + tx.unlock_time + config::graft::TRUSTED_RESTAKING_PERIOD; + //search for a stake of the corresponding supernode supernode_stake_index_map::iterator it = m_supernode_stake_indexes.find(tx.supernode_public_id); @@ -187,8 +197,11 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number) { new_stake.amount = tx.amount; new_stake.tier = get_tier(new_stake.amount); - new_stake.block_height = tx.block_height + config::graft::STAKE_VALIDATION_PERIOD; - new_stake.unlock_time = tx.unlock_time + config::graft::TRUSTED_RESTAKING_PERIOD - config::graft::STAKE_VALIDATION_PERIOD; + 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=" << + new_stake.tier << ", validity=[" << min_tx_block_height << ";" << max_tx_block_height << ")"); } new_stake.supernode_public_id = tx.supernode_public_id; @@ -206,6 +219,9 @@ 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 << + ", validity=[" << min_tx_block_height << ";" << max_tx_block_height << ")"); + supernode_stake& stake = m_supernode_stakes[it->second]; if (!stake.amount) @@ -214,8 +230,8 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number) stake.amount = tx.amount; stake.tier = get_tier(stake.amount); - stake.block_height = tx.block_height + config::graft::STAKE_VALIDATION_PERIOD; - stake.unlock_time = tx.unlock_time + config::graft::TRUSTED_RESTAKING_PERIOD - config::graft::STAKE_VALIDATION_PERIOD; + stake.block_height = min_tx_block_height; + stake.unlock_time = max_tx_block_height - min_tx_block_height; continue; } @@ -227,10 +243,8 @@ void StakeTransactionStorage::update_supernode_stakes(uint64_t block_number) //find intersection of stake transaction intervals - uint64_t min_block_height = stake.block_height, - max_block_height = min_block_height + stake.unlock_time, - min_tx_block_height = tx.block_height, - max_tx_block_height = min_tx_block_height + tx.unlock_time; + uint64_t min_block_height = stake.block_height, + max_block_height = min_block_height + stake.unlock_time; if (min_tx_block_height > min_block_height) min_block_height = min_tx_block_height; @@ -243,6 +257,9 @@ 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 << + ", validity=[" << min_block_height << ";" << max_block_height << ")"); } } catch (...)