aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-01-15 16:05:55 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2017-02-13 21:11:37 +0000
commit0288310e3b4e777dd4d120898319192f957996a2 (patch)
tree43faa373110305f0c4809f3c3e8421c5b973801a /src/cryptonote_core
parentMerge pull request #1719 (diff)
downloadmonero-0288310e3b4e777dd4d120898319192f957996a2.tar.xz
blockchain_db: add "raw" blobdata getters for block and transaction
This speeds up operations such as serving blocks to syncing peers
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/blockchain.cpp91
-rw-r--r--src/cryptonote_core/blockchain.h9
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp30
-rw-r--r--src/cryptonote_core/cryptonote_core.h30
4 files changed, 119 insertions, 41 deletions
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index a81286632..228b1f3e3 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -1431,7 +1431,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id
return true;
}
//------------------------------------------------------------------
-bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) const
+bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks, std::list<cryptonote::blobdata>& txs) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -1443,17 +1443,17 @@ bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block
return false;
}
- for(const block& blk : blocks)
+ for(const auto& blk : blocks)
{
std::list<crypto::hash> missed_ids;
- get_transactions(blk.tx_hashes, txs, missed_ids);
+ get_transactions_blobs(blk.second.tx_hashes, txs, missed_ids);
CHECK_AND_ASSERT_MES(!missed_ids.size(), false, "has missed transactions in own block in main blockchain");
}
return true;
}
//------------------------------------------------------------------
-bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const
+bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -1462,7 +1462,12 @@ bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block
for(size_t i = start_offset; i < start_offset + count && i < m_db->height();i++)
{
- blocks.push_back(m_db->get_block_from_height(i));
+ blocks.push_back(std::make_pair(m_db->get_block_blob_from_height(i), block()));
+ if (!parse_and_validate_block_from_blob(blocks.back().first, blocks.back().second))
+ {
+ LOG_ERROR("Invalid block");
+ return false;
+ }
}
return true;
}
@@ -1480,22 +1485,22 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
CRITICAL_REGION_LOCAL(m_blockchain_lock);
m_db->block_txn_start(true);
rsp.current_blockchain_height = get_current_blockchain_height();
- std::list<block> blocks;
+ std::list<std::pair<cryptonote::blobdata,block>> blocks;
get_blocks(arg.blocks, blocks, rsp.missed_ids);
for (const auto& bl: blocks)
{
std::list<crypto::hash> missed_tx_ids;
- std::list<transaction> txs;
+ std::list<cryptonote::blobdata> txs;
// FIXME: s/rsp.missed_ids/missed_tx_id/ ? Seems like rsp.missed_ids
// is for missed blocks, not missed transactions as well.
- get_transactions(bl.tx_hashes, txs, missed_tx_ids);
+ get_transactions_blobs(bl.second.tx_hashes, txs, missed_tx_ids);
if (missed_tx_ids.size() != 0)
{
LOG_ERROR("Error retrieving blocks, missed " << missed_tx_ids.size()
- << " transactions for block with hash: " << get_block_hash(bl)
+ << " transactions for block with hash: " << get_block_hash(bl.second)
<< std::endl
);
@@ -1510,17 +1515,17 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO
rsp.blocks.push_back(block_complete_entry());
block_complete_entry& e = rsp.blocks.back();
//pack block
- e.block = t_serializable_object_to_blob(bl);
+ e.block = bl.first;
//pack transactions
- for (transaction& tx: txs)
- e.txs.push_back(t_serializable_object_to_blob(tx));
+ for (const cryptonote::blobdata& tx: txs)
+ e.txs.push_back(tx);
}
//get another transactions, if need
- std::list<transaction> txs;
- get_transactions(arg.txs, txs, rsp.missed_ids);
+ std::list<cryptonote::blobdata> txs;
+ get_transactions_blobs(arg.txs, txs, rsp.missed_ids);
//pack aside transactions
for (const auto& tx: txs)
- rsp.txs.push_back(t_serializable_object_to_blob(tx));
+ rsp.txs.push_back(tx);
m_db->block_txn_stop();
return true;
@@ -1889,7 +1894,12 @@ bool Blockchain::get_blocks(const t_ids_container& block_ids, t_blocks_container
{
try
{
- blocks.push_back(m_db->get_block(block_hash));
+ blocks.push_back(std::make_pair(m_db->get_block_blob(block_hash), block()));
+ if (!parse_and_validate_block_from_blob(blocks.back().first, blocks.back().second))
+ {
+ LOG_ERROR("Invalid block");
+ return false;
+ }
}
catch (const BLOCK_DNE& e)
{
@@ -1906,7 +1916,7 @@ bool Blockchain::get_blocks(const t_ids_container& block_ids, t_blocks_container
//TODO: return type should be void, throw on exception
// alternatively, return true only if no transactions missed
template<class t_ids_container, class t_tx_container, class t_missed_container>
-bool Blockchain::get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const
+bool Blockchain::get_transactions_blobs(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -1915,8 +1925,8 @@ bool Blockchain::get_transactions(const t_ids_container& txs_ids, t_tx_container
{
try
{
- transaction tx;
- if (m_db->get_tx(tx_hash, tx))
+ cryptonote::blobdata tx;
+ if (m_db->get_tx_blob(tx_hash, tx))
txs.push_back(std::move(tx));
else
missed_txs.push_back(tx_hash);
@@ -1929,6 +1939,37 @@ bool Blockchain::get_transactions(const t_ids_container& txs_ids, t_tx_container
return true;
}
//------------------------------------------------------------------
+template<class t_ids_container, class t_tx_container, class t_missed_container>
+bool Blockchain::get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const
+{
+ LOG_PRINT_L3("Blockchain::" << __func__);
+ CRITICAL_REGION_LOCAL(m_blockchain_lock);
+
+ for (const auto& tx_hash : txs_ids)
+ {
+ try
+ {
+ cryptonote::blobdata tx;
+ if (m_db->get_tx_blob(tx_hash, tx))
+ {
+ txs.push_back(transaction());
+ if (!parse_and_validate_tx_from_blob(tx, txs.back()))
+ {
+ LOG_ERROR("Invalid transaction");
+ return false;
+ }
+ }
+ else
+ missed_txs.push_back(tx_hash);
+ }
+ catch (const std::exception& e)
+ {
+ return false;
+ }
+ }
+ return true;
+}
+//------------------------------------------------------------------
void Blockchain::print_blockchain(uint64_t start_index, uint64_t end_index) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
@@ -1999,7 +2040,7 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc
// find split point between ours and foreign blockchain (or start at
// blockchain height <req_start_block>), and return up to max_count FULL
// blocks by reference.
-bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const
+bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
@@ -2027,9 +2068,11 @@ bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, cons
for(size_t i = start_height; i < total_height && count < max_count; i++, count++)
{
blocks.resize(blocks.size()+1);
- blocks.back().first = m_db->get_block_from_height(i);
+ blocks.back().first = m_db->get_block_blob_from_height(i);
+ block b;
+ CHECK_AND_ASSERT_MES(parse_and_validate_block_from_blob(blocks.back().first, b), false, "internal error, invalid block");
std::list<crypto::hash> mis;
- get_transactions(blocks.back().first.tx_hashes, blocks.back().second, mis);
+ get_transactions_blobs(b.tx_hashes, blocks.back().second, mis);
CHECK_AND_ASSERT_MES(!mis.size(), false, "internal error, transaction from block not found");
}
return true;
@@ -4011,3 +4054,7 @@ bool Blockchain::for_all_outputs(std::function<bool(uint64_t amount, const crypt
{
return m_db->for_all_outputs(f);;
}
+
+namespace cryptonote {
+template bool Blockchain::get_transactions(const std::vector<crypto::hash>&, std::list<transaction>&, std::list<crypto::hash>&) const;
+}
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index c806c3505..7315ea735 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -153,7 +153,7 @@ namespace cryptonote
*
* @return false if start_offset > blockchain height, else true
*/
- bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) const;
+ bool get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks, std::list<cryptonote::blobdata>& txs) const;
/**
* @brief get blocks from blocks based on start height and count
@@ -164,7 +164,7 @@ namespace cryptonote
*
* @return false if start_offset > blockchain height, else true
*/
- bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const;
+ bool get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks) const;
/**
* @brief compiles a list of all blocks stored as alternative chains
@@ -407,7 +407,7 @@ namespace cryptonote
*
* @return true if a block found in common or req_start_block specified, else false
*/
- bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const;
+ bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const;
/**
* @brief retrieves a set of blocks and their transactions, and possibly other transactions
@@ -621,9 +621,10 @@ namespace cryptonote
* @return false if an unexpected exception occurs, else true
*/
template<class t_ids_container, class t_tx_container, class t_missed_container>
+ bool get_transactions_blobs(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const;
+ template<class t_ids_container, class t_tx_container, class t_missed_container>
bool get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const;
-
//debug functions
/**
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index b940dba3c..b7ea26109 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -195,15 +195,31 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
- bool core::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) const
+ bool core::get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks, std::list<cryptonote::blobdata>& txs) const
{
return m_blockchain_storage.get_blocks(start_offset, count, blocks, txs);
}
//-----------------------------------------------------------------------------------------------
- bool core::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const
+ bool core::get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks) const
{
return m_blockchain_storage.get_blocks(start_offset, count, blocks);
- } //-----------------------------------------------------------------------------------------------
+ }
+ //-----------------------------------------------------------------------------------------------
+ bool core::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const
+ {
+ std::list<std::pair<cryptonote::blobdata, cryptonote::block>> bs;
+ if (!m_blockchain_storage.get_blocks(start_offset, count, bs))
+ return false;
+ for (const auto &b: bs)
+ blocks.push_back(b.second);
+ return true;
+ }
+ //-----------------------------------------------------------------------------------------------
+ bool core::get_transactions(const std::vector<crypto::hash>& txs_ids, std::list<cryptonote::blobdata>& txs, std::list<crypto::hash>& missed_txs) const
+ {
+ return m_blockchain_storage.get_transactions_blobs(txs_ids, txs, missed_txs);
+ }
+ //-----------------------------------------------------------------------------------------------
bool core::get_transactions(const std::vector<crypto::hash>& txs_ids, std::list<transaction>& txs, std::list<crypto::hash>& missed_txs) const
{
return m_blockchain_storage.get_transactions(txs_ids, txs, missed_txs);
@@ -799,7 +815,7 @@ namespace cryptonote
return m_blockchain_storage.find_blockchain_supplement(qblock_ids, resp);
}
//-----------------------------------------------------------------------------------------------
- bool core::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const
+ bool core::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const
{
return m_blockchain_storage.find_blockchain_supplement(req_start_block, qblock_ids, blocks, total_height, start_height, max_count);
}
@@ -867,8 +883,8 @@ namespace cryptonote
arg.hop = 0;
arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_height();
std::list<crypto::hash> missed_txs;
- std::list<transaction> txs;
- m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs);
+ std::list<cryptonote::blobdata> txs;
+ m_blockchain_storage.get_transactions_blobs(b.tx_hashes, txs, missed_txs);
if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b))
{
LOG_PRINT_L1("Block found but, seems that reorganize just happened after that, do not relay this block");
@@ -880,7 +896,7 @@ namespace cryptonote
block_to_blob(b, arg.b.block);
//pack transactions
for(auto& tx: txs)
- arg.b.txs.push_back(t_serializable_object_to_blob(tx));
+ arg.b.txs.push_back(tx);
m_pprotocol->relay_block(arg, exclude_context);
}
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index fe1d11916..1c06e5924 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -287,16 +287,23 @@ namespace cryptonote
bool get_blockchain_top(uint64_t& height, crypto::hash& top_id) const;
/**
- * @copydoc Blockchain::get_blocks(uint64_t, size_t, std::list<block>&, std::list<transaction>&) const
+ * @copydoc Blockchain::get_blocks(uint64_t, size_t, std::list<std::pair<cryptonote::blobdata,block>>&, std::list<transaction>&) const
*
- * @note see Blockchain::get_blocks(uint64_t, size_t, std::list<block>&, std::list<transaction>&) const
+ * @note see Blockchain::get_blocks(uint64_t, size_t, std::list<std::pair<cryptonote::blobdata,block>>&, std::list<transaction>&) const
*/
- bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) const;
+ bool get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks, std::list<cryptonote::blobdata>& txs) const;
/**
- * @copydoc Blockchain::get_blocks(uint64_t, size_t, std::list<block>&) const
+ * @copydoc Blockchain::get_blocks(uint64_t, size_t, std::list<std::pair<cryptonote::blobdata,block>>&) const
*
- * @note see Blockchain::get_blocks(uint64_t, size_t, std::list<block>&) const
+ * @note see Blockchain::get_blocks(uint64_t, size_t, std::list<std::pair<cryptonote::blobdata,block>>&) const
+ */
+ bool get_blocks(uint64_t start_offset, size_t count, std::list<std::pair<cryptonote::blobdata,block>>& blocks) const;
+
+ /**
+ * @copydoc Blockchain::get_blocks(uint64_t, size_t, std::list<std::pair<cryptonote::blobdata,block>>&) const
+ *
+ * @note see Blockchain::get_blocks(uint64_t, size_t, std::list<std::pair<cryptonote::blobdata,block>>&) const
*/
bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const;
@@ -323,6 +330,13 @@ namespace cryptonote
*
* @note see Blockchain::get_transactions
*/
+ bool get_transactions(const std::vector<crypto::hash>& txs_ids, std::list<cryptonote::blobdata>& txs, std::list<crypto::hash>& missed_txs) const;
+
+ /**
+ * @copydoc Blockchain::get_transactions
+ *
+ * @note see Blockchain::get_transactions
+ */
bool get_transactions(const std::vector<crypto::hash>& txs_ids, std::list<transaction>& txs, std::list<crypto::hash>& missed_txs) const;
/**
@@ -431,11 +445,11 @@ namespace cryptonote
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const;
/**
- * @copydoc Blockchain::find_blockchain_supplement(const uint64_t, const std::list<crypto::hash>&, std::list<std::pair<block, std::list<transaction> > >&, uint64_t&, uint64_t&, size_t) const
+ * @copydoc Blockchain::find_blockchain_supplement(const uint64_t, const std::list<crypto::hash>&, std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > >&, uint64_t&, uint64_t&, size_t) const
*
- * @note see Blockchain::find_blockchain_supplement(const uint64_t, const std::list<crypto::hash>&, std::list<std::pair<block, std::list<transaction> > >&, uint64_t&, uint64_t&, size_t) const
+ * @note see Blockchain::find_blockchain_supplement(const uint64_t, const std::list<crypto::hash>&, std::list<std::pair<cryptonote::blobdata, std::list<transaction> > >&, uint64_t&, uint64_t&, size_t) const
*/
- bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const;
+ bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<cryptonote::blobdata, std::list<cryptonote::blobdata> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const;
/**
* @brief gets some stats about the daemon