aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp103
-rw-r--r--src/cryptonote_core/blockchain.h4
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp5
-rw-r--r--src/cryptonote_core/cryptonote_core.h1
4 files changed, 38 insertions, 75 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index bbac20eaa..d8163721e 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -641,6 +641,9 @@ block Blockchain::pop_block_from_blockchain()
throw;
}
+ // make sure the hard fork object updates its current version
+ m_hardfork->on_block_popped(1);
+
// return transactions from popped block to the tx_pool
for (transaction& tx : popped_txs)
{
@@ -651,12 +654,7 @@ block Blockchain::pop_block_from_blockchain()
// FIXME: HardFork
// Besides the below, popping a block should also remove the last entry
// in hf_versions.
- //
- // FIXME: HardFork
- // This is not quite correct, as we really want to add the txes
- // to the pool based on the version determined after all blocks
- // are popped.
- uint8_t version = get_current_hard_fork_version();
+ uint8_t version = get_ideal_hard_fork_version(m_db->height());
// We assume that if they were in a block, the transactions are already
// known to the network as a whole. However, if we had mined that block,
@@ -921,8 +919,10 @@ difficulty_type Blockchain::get_difficulty_for_next_block()
//------------------------------------------------------------------
std::vector<time_t> Blockchain::get_last_block_timestamps(unsigned int blocks) const
{
- std::vector<time_t> timestamps(blocks);
uint64_t height = m_db->height();
+ if (blocks > height)
+ blocks = height;
+ std::vector<time_t> timestamps(blocks);
while (blocks--)
timestamps[blocks] = m_db->get_block_timestamp(height - blocks - 1);
return timestamps;
@@ -1199,7 +1199,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
return false;
}
// From hard fork 2, we allow a miner to claim less block reward than is allowed, in case a miner wants less dust
- if (m_hardfork->get_current_version() < 2)
+ if (version < 2)
{
if(base_reward + fee != money_in_use)
{
@@ -2298,7 +2298,7 @@ bool Blockchain::check_for_double_spend(const transaction& tx, key_images_contai
return true;
}
//------------------------------------------------------------------
-bool Blockchain::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const
+bool Blockchain::get_tx_outputs_gindexs(const crypto::hash& tx_id, size_t n_txes, std::vector<std::vector<uint64_t>>& indexs) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -2308,16 +2308,25 @@ bool Blockchain::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<u
MERROR_VER("get_tx_outputs_gindexs failed to find transaction with id = " << tx_id);
return false;
}
+ indexs = m_db->get_tx_amount_output_indices(tx_index, n_txes);
+ CHECK_AND_ASSERT_MES(n_txes == indexs.size(), false, "Wrong indexs size");
- // get amount output indexes, currently referred to in parts as "output global indices", but they are actually specific to amounts
- indexs = m_db->get_tx_amount_output_indices(tx_index);
- if (indexs.empty())
+ return true;
+}
+//------------------------------------------------------------------
+bool Blockchain::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const
+{
+ LOG_PRINT_L3("Blockchain::" << __func__);
+ CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ uint64_t tx_index;
+ if (!m_db->tx_exists(tx_id, tx_index))
{
- // empty indexs is only valid if the vout is empty, which is legal but rare
- cryptonote::transaction tx = m_db->get_tx(tx_id);
- CHECK_AND_ASSERT_MES(tx.vout.empty(), false, "internal error: global indexes for transaction " << tx_id << " is empty, and tx vout is not");
+ MERROR_VER("get_tx_outputs_gindexs failed to find transaction with id = " << tx_id);
+ return false;
}
-
+ std::vector<std::vector<uint64_t>> indices = m_db->get_tx_amount_output_indices(tx_index, 1);
+ CHECK_AND_ASSERT_MES(indices.size() == 1, false, "Wrong indices size");
+ indexs = indices.front();
return true;
}
//------------------------------------------------------------------
@@ -3842,33 +3851,11 @@ bool Blockchain::cleanup_handle_incoming_blocks(bool force_sync)
}
//------------------------------------------------------------------
-void Blockchain::output_scan_worker(const uint64_t amount, const std::vector<uint64_t> &offsets, std::vector<output_data_t> &outputs, const std::vector<output_data_t> &extra_tx_map) const
+void Blockchain::output_scan_worker(const uint64_t amount, const std::vector<uint64_t> &offsets, std::vector<output_data_t> &outputs) const
{
try
{
m_db->get_output_key(epee::span<const uint64_t>(&amount, 1), offsets, outputs, true);
- if (outputs.size() < offsets.size())
- {
- const uint64_t n_outputs = m_db->get_num_outputs(amount);
- for (size_t i = outputs.size(); i < offsets.size(); ++i)
- {
- uint64_t idx = offsets[i];
- if (idx < n_outputs)
- {
- MWARNING("Index " << idx << " not found in db for amount " << amount << ", but it is less than the number of entries");
- break;
- }
- else if (idx < n_outputs + extra_tx_map.size())
- {
- outputs.push_back(extra_tx_map[idx - n_outputs]);
- }
- else
- {
- MWARNING("missed " << amount << "/" << idx << " in " << extra_tx_map.size() << " (chain " << n_outputs << ")");
- break;
- }
- }
- }
}
catch (const std::exception& e)
{
@@ -3983,34 +3970,6 @@ uint64_t Blockchain::prevalidate_block_hashes(uint64_t height, const std::vector
// vs [k_image, output_keys] (m_scan_table). This is faster because it takes advantage of bulk queries
// and is threaded if possible. The table (m_scan_table) will be used later when querying output
// keys.
-static bool update_output_map(std::map<uint64_t, std::vector<output_data_t>> &extra_tx_map, const transaction &tx, uint64_t height, bool miner)
-{
- MTRACE("Blockchain::" << __func__);
- for (size_t i = 0; i < tx.vout.size(); ++i)
- {
- const auto &out = tx.vout[i];
- if (out.target.type() != typeid(txout_to_key))
- continue;
- const txout_to_key &out_to_key = boost::get<txout_to_key>(out.target);
- rct::key commitment;
- uint64_t amount = out.amount;
- if (miner && tx.version == 2)
- {
- commitment = rct::zeroCommit(amount);
- amount = 0;
- }
- else if (tx.version > 1)
- {
- CHECK_AND_ASSERT_MES(i < tx.rct_signatures.outPk.size(), false, "Invalid outPk size");
- commitment = tx.rct_signatures.outPk[i].mask;
- }
- else
- commitment = rct::zero();
- extra_tx_map[amount].push_back(output_data_t{out_to_key.key, tx.unlock_time, height, commitment});
- }
- return true;
-}
-
bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete_entry> &blocks_entry)
{
MTRACE("Blockchain::" << __func__);
@@ -4179,7 +4138,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
// [input] stores all absolute_offsets for each amount
std::map<uint64_t, std::vector<uint64_t>> offset_map;
// [output] stores all output_data_t for each absolute_offset
- std::map<uint64_t, std::vector<output_data_t>> tx_map, extra_tx_map;
+ std::map<uint64_t, std::vector<output_data_t>> tx_map;
std::vector<std::pair<cryptonote::transaction, crypto::hash>> txes(total_txs);
#define SCAN_TABLE_QUIT(m) \
@@ -4196,8 +4155,6 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
if (m_cancel)
return false;
- if (!update_output_map(extra_tx_map, blocks[block_index].miner_tx, height + block_index, true))
- SCAN_TABLE_QUIT("Error building extra tx map.");
for (const auto &tx_blob : entry.txs)
{
if (tx_index >= txes.size())
@@ -4256,8 +4213,6 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
offset_map[in_to_key.amount].push_back(offset);
}
- if (!update_output_map(extra_tx_map, tx, height + block_index, false))
- SCAN_TABLE_QUIT("Error building extra tx map.");
}
++block_index;
}
@@ -4282,7 +4237,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
for (size_t i = 0; i < amounts.size(); i++)
{
uint64_t amount = amounts[i];
- tpool.submit(&waiter, boost::bind(&Blockchain::output_scan_worker, this, amount, std::cref(offset_map[amount]), std::ref(tx_map[amount]), std::cref(extra_tx_map[amount])), true);
+ tpool.submit(&waiter, boost::bind(&Blockchain::output_scan_worker, this, amount, std::cref(offset_map[amount]), std::ref(tx_map[amount])), true);
}
waiter.wait(&tpool);
}
@@ -4291,7 +4246,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
for (size_t i = 0; i < amounts.size(); i++)
{
uint64_t amount = amounts[i];
- output_scan_worker(amount, offset_map[amount], tx_map[amount], extra_tx_map[amount]);
+ output_scan_worker(amount, offset_map[amount], tx_map[amount]);
}
}
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 67bccc6c6..5a1c4b9ad 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -521,10 +521,12 @@ namespace cryptonote
*
* @param tx_id the hash of the transaction to fetch indices for
* @param indexs return-by-reference the global indices for the transaction's outputs
+ * @param n_txes how many txes in a row to get results for
*
* @return false if the transaction does not exist, or if no indices are found, otherwise true
*/
bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const;
+ bool get_tx_outputs_gindexs(const crypto::hash& tx_id, size_t n_txes, std::vector<std::vector<uint64_t>>& indexs) const;
/**
* @brief stores the blockchain
@@ -923,7 +925,7 @@ namespace cryptonote
* @param outputs return-by-reference the outputs collected
*/
void output_scan_worker(const uint64_t amount,const std::vector<uint64_t> &offsets,
- std::vector<output_data_t> &outputs, const std::vector<output_data_t> &extra_tx_map) const;
+ std::vector<output_data_t> &outputs) const;
/**
* @brief computes the "short" and "long" hashes for a set of blocks
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index f3249ea92..1fa6969a6 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -1220,6 +1220,11 @@ namespace cryptonote
return m_blockchain_storage.get_tx_outputs_gindexs(tx_id, indexs);
}
//-----------------------------------------------------------------------------------------------
+ bool core::get_tx_outputs_gindexs(const crypto::hash& tx_id, size_t n_txes, std::vector<std::vector<uint64_t>>& indexs) const
+ {
+ return m_blockchain_storage.get_tx_outputs_gindexs(tx_id, n_txes, indexs);
+ }
+ //-----------------------------------------------------------------------------------------------
void core::pause_mine()
{
m_miner.pause();
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index cc53fce58..fe86f8d39 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -534,6 +534,7 @@ namespace cryptonote
* @note see Blockchain::get_tx_outputs_gindexs
*/
bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const;
+ bool get_tx_outputs_gindexs(const crypto::hash& tx_id, size_t n_txes, std::vector<std::vector<uint64_t>>& indexs) const;
/**
* @copydoc Blockchain::get_tail_id