diff options
author | Thomas Winget <tewinget@gmail.com> | 2014-12-08 15:38:55 -0500 |
---|---|---|
committer | warptangent <warptangent@inbox.com> | 2015-01-04 19:39:42 -0800 |
commit | 53ce3c95d9b21aac558f8e569d90fc05e0df3e8c (patch) | |
tree | a3e2645b51f2c1f3b6fd77ebdc889afe1fcc96bd | |
parent | Merge pull request #13 from moneromooo-monero/blockchain (diff) | |
parent | blockchain: fix wallet syncing from scratch (diff) | |
download | monero-53ce3c95d9b21aac558f8e569d90fc05e0df3e8c.tar.xz |
Merge pull request #14 from moneromooo-monero/blockchain
Blockchain
lots of const-correctness and more proper code, bug fix with syncing.
-rw-r--r-- | src/blockchain_converter/blockchain_converter.cpp | 1 | ||||
-rw-r--r-- | src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp | 115 | ||||
-rw-r--r-- | src/cryptonote_core/BlockchainDB_impl/db_lmdb.h | 70 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 89 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.h | 82 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain_db.h | 258 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain_storage.cpp | 126 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain_storage.h | 116 | ||||
-rw-r--r-- | src/cryptonote_core/checkpoints.cpp | 8 | ||||
-rw-r--r-- | src/cryptonote_core/checkpoints.h | 6 |
10 files changed, 384 insertions, 487 deletions
diff --git a/src/blockchain_converter/blockchain_converter.cpp b/src/blockchain_converter/blockchain_converter.cpp index a2b3a375f..4653cf66c 100644 --- a/src/blockchain_converter/blockchain_converter.cpp +++ b/src/blockchain_converter/blockchain_converter.cpp @@ -99,5 +99,6 @@ int main(int argc, char* argv[]) } } + delete blockchain; return 0; } diff --git a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp index a123a3643..278bec14f 100644 --- a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp +++ b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.cpp @@ -67,6 +67,7 @@ struct lmdb_cur } } +private: MDB_cursor* m_cur; bool done; }; @@ -79,26 +80,26 @@ auto compare_uint64 = [](const MDB_val *a, const MDB_val *b) { else return 1; }; -const char* LMDB_BLOCKS = "blocks"; -const char* LMDB_BLOCK_TIMESTAMPS = "block_timestamps"; -const char* LMDB_BLOCK_HEIGHTS = "block_heights"; -const char* LMDB_BLOCK_HASHES = "block_hashes"; -const char* LMDB_BLOCK_SIZES = "block_sizes"; -const char* LMDB_BLOCK_DIFFS = "block_diffs"; -const char* LMDB_BLOCK_COINS = "block_coins"; - -const char* LMDB_TXS = "txs"; -const char* LMDB_TX_UNLOCKS = "tx_unlocks"; -const char* LMDB_TX_HEIGHTS = "tx_heights"; -const char* LMDB_TX_OUTPUTS = "tx_outputs"; - -const char* LMDB_OUTPUT_TXS = "output_txs"; -const char* LMDB_OUTPUT_INDICES = "output_indices"; -const char* LMDB_OUTPUT_AMOUNTS = "output_amounts"; -const char* LMDB_OUTPUT_KEYS = "output_keys"; -const char* LMDB_OUTPUTS = "outputs"; -const char* LMDB_OUTPUT_GINDICES = "output_gindices"; -const char* LMDB_SPENT_KEYS = "spent_keys"; +const char* const LMDB_BLOCKS = "blocks"; +const char* const LMDB_BLOCK_TIMESTAMPS = "block_timestamps"; +const char* const LMDB_BLOCK_HEIGHTS = "block_heights"; +const char* const LMDB_BLOCK_HASHES = "block_hashes"; +const char* const LMDB_BLOCK_SIZES = "block_sizes"; +const char* const LMDB_BLOCK_DIFFS = "block_diffs"; +const char* const LMDB_BLOCK_COINS = "block_coins"; + +const char* const LMDB_TXS = "txs"; +const char* const LMDB_TX_UNLOCKS = "tx_unlocks"; +const char* const LMDB_TX_HEIGHTS = "tx_heights"; +const char* const LMDB_TX_OUTPUTS = "tx_outputs"; + +const char* const LMDB_OUTPUT_TXS = "output_txs"; +const char* const LMDB_OUTPUT_INDICES = "output_indices"; +const char* const LMDB_OUTPUT_AMOUNTS = "output_amounts"; +const char* const LMDB_OUTPUT_KEYS = "output_keys"; +const char* const LMDB_OUTPUTS = "outputs"; +const char* const LMDB_OUTPUT_GINDICES = "output_gindices"; +const char* const LMDB_SPENT_KEYS = "spent_keys"; inline void lmdb_db_open(MDB_txn* txn, const char* name, int flags, MDB_dbi& dbi, const std::string& error_string) { @@ -628,7 +629,7 @@ blobdata BlockchainLMDB::output_to_blob(const tx_out& output) return b; } -tx_out BlockchainLMDB::output_from_blob(const blobdata& blob) +tx_out BlockchainLMDB::output_from_blob(const blobdata& blob) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); std::stringstream ss; @@ -645,13 +646,13 @@ tx_out BlockchainLMDB::output_from_blob(const blobdata& blob) return o; } -uint64_t BlockchainLMDB::get_output_global_index(const uint64_t& amount, const uint64_t& index) +uint64_t BlockchainLMDB::get_output_global_index(const uint64_t& amount, const uint64_t& index) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); return 0; } -void BlockchainLMDB::check_open() +void BlockchainLMDB::check_open() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); if (!m_open) @@ -821,7 +822,7 @@ void BlockchainLMDB::reset() // TODO: this } -std::vector<std::string> BlockchainLMDB::get_filenames() +std::vector<std::string> BlockchainLMDB::get_filenames() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); std::vector<std::string> filenames; @@ -853,7 +854,7 @@ void BlockchainLMDB::unlock() } -bool BlockchainLMDB::block_exists(const crypto::hash& h) +bool BlockchainLMDB::block_exists(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -888,7 +889,7 @@ bool BlockchainLMDB::block_exists(const crypto::hash& h) return true; } -block BlockchainLMDB::get_block(const crypto::hash& h) +block BlockchainLMDB::get_block(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -896,7 +897,7 @@ block BlockchainLMDB::get_block(const crypto::hash& h) return get_block_from_height(get_block_height(h)); } -uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) +uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -930,7 +931,7 @@ uint64_t BlockchainLMDB::get_block_height(const crypto::hash& h) return *(uint64_t*)result.mv_data; } -block_header BlockchainLMDB::get_block_header(const crypto::hash& h) +block_header BlockchainLMDB::get_block_header(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -939,7 +940,7 @@ block_header BlockchainLMDB::get_block_header(const crypto::hash& h) return get_block(h); } -block BlockchainLMDB::get_block_from_height(const uint64_t& height) +block BlockchainLMDB::get_block_from_height(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -983,7 +984,7 @@ block BlockchainLMDB::get_block_from_height(const uint64_t& height) return b; } -uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) +uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1016,7 +1017,7 @@ uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) return *(uint64_t*)result.mv_data; } -uint64_t BlockchainLMDB::get_top_block_timestamp() +uint64_t BlockchainLMDB::get_top_block_timestamp() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1030,7 +1031,7 @@ uint64_t BlockchainLMDB::get_top_block_timestamp() return get_block_timestamp(m_height - 1); } -size_t BlockchainLMDB::get_block_size(const uint64_t& height) +size_t BlockchainLMDB::get_block_size(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1063,7 +1064,7 @@ size_t BlockchainLMDB::get_block_size(const uint64_t& height) return *(size_t*)result.mv_data; } -difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t& height) +difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1096,7 +1097,7 @@ difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t& return *(difficulty_type*)result.mv_data; } -difficulty_type BlockchainLMDB::get_block_difficulty(const uint64_t& height) +difficulty_type BlockchainLMDB::get_block_difficulty(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1113,7 +1114,7 @@ difficulty_type BlockchainLMDB::get_block_difficulty(const uint64_t& height) return diff1 - diff2; } -uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& height) +uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1146,7 +1147,7 @@ uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& heigh return *(uint64_t*)result.mv_data; } -crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) +crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1179,7 +1180,7 @@ crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) return *(crypto::hash*)result.mv_data; } -std::vector<block> BlockchainLMDB::get_blocks_range(const uint64_t& h1, const uint64_t& h2) +std::vector<block> BlockchainLMDB::get_blocks_range(const uint64_t& h1, const uint64_t& h2) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1193,7 +1194,7 @@ std::vector<block> BlockchainLMDB::get_blocks_range(const uint64_t& h1, const ui return v; } -std::vector<crypto::hash> BlockchainLMDB::get_hashes_range(const uint64_t& h1, const uint64_t& h2) +std::vector<crypto::hash> BlockchainLMDB::get_hashes_range(const uint64_t& h1, const uint64_t& h2) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1207,7 +1208,7 @@ std::vector<crypto::hash> BlockchainLMDB::get_hashes_range(const uint64_t& h1, c return v; } -crypto::hash BlockchainLMDB::top_block_hash() +crypto::hash BlockchainLMDB::top_block_hash() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1219,7 +1220,7 @@ crypto::hash BlockchainLMDB::top_block_hash() return null_hash; } -block BlockchainLMDB::get_top_block() +block BlockchainLMDB::get_top_block() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1233,7 +1234,7 @@ block BlockchainLMDB::get_top_block() return b; } -uint64_t BlockchainLMDB::height() +uint64_t BlockchainLMDB::height() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1242,7 +1243,7 @@ uint64_t BlockchainLMDB::height() } -bool BlockchainLMDB::tx_exists(const crypto::hash& h) +bool BlockchainLMDB::tx_exists(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1276,7 +1277,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h) return true; } -uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) +uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1309,7 +1310,7 @@ uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) return *(uint64_t*)result.mv_data; } -transaction BlockchainLMDB::get_tx(const crypto::hash& h) +transaction BlockchainLMDB::get_tx(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1352,7 +1353,7 @@ transaction BlockchainLMDB::get_tx(const crypto::hash& h) return tx; } -uint64_t BlockchainLMDB::get_tx_count() +uint64_t BlockchainLMDB::get_tx_count() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1376,7 +1377,7 @@ uint64_t BlockchainLMDB::get_tx_count() return db_stats.ms_entries; } -std::vector<transaction> BlockchainLMDB::get_tx_list(const std::vector<crypto::hash>& hlist) +std::vector<transaction> BlockchainLMDB::get_tx_list(const std::vector<crypto::hash>& hlist) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1390,7 +1391,7 @@ std::vector<transaction> BlockchainLMDB::get_tx_list(const std::vector<crypto::h return v; } -uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) +uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1424,7 +1425,7 @@ uint64_t BlockchainLMDB::get_tx_block_height(const crypto::hash& h) } //FIXME: make sure the random method used here is appropriate -uint64_t BlockchainLMDB::get_random_output(const uint64_t& amount) +uint64_t BlockchainLMDB::get_random_output(const uint64_t& amount) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1439,7 +1440,7 @@ uint64_t BlockchainLMDB::get_random_output(const uint64_t& amount) return crypto::rand<uint64_t>() % num_outputs; } -uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) +uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1478,7 +1479,7 @@ uint64_t BlockchainLMDB::get_num_outputs(const uint64_t& amount) return num_elems; } -crypto::public_key BlockchainLMDB::get_output_key(const uint64_t& amount, const uint64_t& index) +crypto::public_key BlockchainLMDB::get_output_key(const uint64_t& amount, const uint64_t& index) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1512,7 +1513,7 @@ crypto::public_key BlockchainLMDB::get_output_key(const uint64_t& amount, const return *(crypto::public_key*)v.mv_data; } -tx_out BlockchainLMDB::get_output(const crypto::hash& h, const uint64_t& index) +tx_out BlockchainLMDB::get_output(const crypto::hash& h, const uint64_t& index) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1576,7 +1577,7 @@ tx_out BlockchainLMDB::get_output(const crypto::hash& h, const uint64_t& index) // As this is not used, its return is now a blank output. // This will save on space in the db. -tx_out BlockchainLMDB::get_output(const uint64_t& index) +tx_out BlockchainLMDB::get_output(const uint64_t& index) const { return tx_out(); LOG_PRINT_L3("BlockchainLMDB::" << __func__); @@ -1612,7 +1613,7 @@ tx_out BlockchainLMDB::get_output(const uint64_t& index) return output_from_blob(b); } -tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) +tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1702,7 +1703,7 @@ tx_out_index BlockchainLMDB::get_output_tx_and_index(const uint64_t& amount, con return tx_out_index(tx_hash, *(uint64_t *)v.mv_data); } -std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash& h) +std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash& h) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1754,7 +1755,7 @@ std::vector<uint64_t> BlockchainLMDB::get_tx_output_indices(const crypto::hash& return index_vec; } -bool BlockchainLMDB::has_key_image(const crypto::key_image& img) +bool BlockchainLMDB::has_key_image(const crypto::key_image& img) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1803,12 +1804,14 @@ uint64_t BlockchainLMDB::add_block( const block& blk try { BlockchainDB::add_block(blk, block_size, cumulative_difficulty, coins_generated, txs); + m_write_txn = NULL; txn.commit(); } catch (...) { m_num_outputs = num_outputs; + m_write_txn = NULL; throw; } @@ -1829,12 +1832,14 @@ void BlockchainLMDB::pop_block(block& blk, std::vector<transaction>& txs) try { BlockchainDB::pop_block(blk, txs); + m_write_txn = NULL; txn.commit(); } catch (...) { m_num_outputs = num_outputs; + m_write_txn = NULL; throw; } diff --git a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h index e74ca4b73..3bac5d740 100644 --- a/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h +++ b/src/cryptonote_core/BlockchainDB_impl/db_lmdb.h @@ -90,65 +90,65 @@ public: virtual void reset(); - virtual std::vector<std::string> get_filenames(); + virtual std::vector<std::string> get_filenames() const; virtual bool lock(); virtual void unlock(); - virtual bool block_exists(const crypto::hash& h); + virtual bool block_exists(const crypto::hash& h) const; - virtual block get_block(const crypto::hash& h); + virtual block get_block(const crypto::hash& h) const; - virtual uint64_t get_block_height(const crypto::hash& h); + virtual uint64_t get_block_height(const crypto::hash& h) const; - virtual block_header get_block_header(const crypto::hash& h); + virtual block_header get_block_header(const crypto::hash& h) const; - virtual block get_block_from_height(const uint64_t& height); + virtual block get_block_from_height(const uint64_t& height) const; - virtual uint64_t get_block_timestamp(const uint64_t& height) ; + virtual uint64_t get_block_timestamp(const uint64_t& height) const; - virtual uint64_t get_top_block_timestamp(); + virtual uint64_t get_top_block_timestamp() const; - virtual size_t get_block_size(const uint64_t& height); + virtual size_t get_block_size(const uint64_t& height) const; - virtual difficulty_type get_block_cumulative_difficulty(const uint64_t& height); + virtual difficulty_type get_block_cumulative_difficulty(const uint64_t& height) const; - virtual difficulty_type get_block_difficulty(const uint64_t& height); + virtual difficulty_type get_block_difficulty(const uint64_t& height) const; - virtual uint64_t get_block_already_generated_coins(const uint64_t& height); + virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const; - virtual crypto::hash get_block_hash_from_height(const uint64_t& height); + virtual crypto::hash get_block_hash_from_height(const uint64_t& height) const; - virtual std::vector<block> get_blocks_range(const uint64_t& h1, const uint64_t& h2); + virtual std::vector<block> get_blocks_range(const uint64_t& h1, const uint64_t& h2) const; - virtual std::vector<crypto::hash> get_hashes_range(const uint64_t& h1, const uint64_t& h2); + virtual std::vector<crypto::hash> get_hashes_range(const uint64_t& h1, const uint64_t& h2) const; - virtual crypto::hash top_block_hash(); + virtual crypto::hash top_block_hash() const; - virtual block get_top_block(); + virtual block get_top_block() const; - virtual uint64_t height(); + virtual uint64_t height() const; - virtual bool tx_exists(const crypto::hash& h); + virtual bool tx_exists(const crypto::hash& h) const; - virtual uint64_t get_tx_unlock_time(const crypto::hash& h); + virtual uint64_t get_tx_unlock_time(const crypto::hash& h) const; - virtual transaction get_tx(const crypto::hash& h); + virtual transaction get_tx(const crypto::hash& h) const; - virtual uint64_t get_tx_count(); + virtual uint64_t get_tx_count() const; - virtual std::vector<transaction> get_tx_list(const std::vector<crypto::hash>& hlist); + virtual std::vector<transaction> get_tx_list(const std::vector<crypto::hash>& hlist) const; - virtual uint64_t get_tx_block_height(const crypto::hash& h); + virtual uint64_t get_tx_block_height(const crypto::hash& h) const; - virtual uint64_t get_random_output(const uint64_t& amount); + virtual uint64_t get_random_output(const uint64_t& amount) const; - virtual uint64_t get_num_outputs(const uint64_t& amount); + virtual uint64_t get_num_outputs(const uint64_t& amount) const; - virtual crypto::public_key get_output_key(const uint64_t& amount, const uint64_t& index); + virtual crypto::public_key get_output_key(const uint64_t& amount, const uint64_t& index) const; - virtual tx_out get_output(const crypto::hash& h, const uint64_t& index); + virtual tx_out get_output(const crypto::hash& h, const uint64_t& index) const; /** * @brief get an output from its global index @@ -159,13 +159,13 @@ public: * Will throw OUTPUT_DNE if not output has that global index. * Will throw DB_ERROR if there is a non-specific LMDB error in fetching */ - tx_out get_output(const uint64_t& index); + tx_out get_output(const uint64_t& index) const; - virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index); + virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const; - virtual std::vector<uint64_t> get_tx_output_indices(const crypto::hash& h); + virtual std::vector<uint64_t> get_tx_output_indices(const crypto::hash& h) const; - virtual bool has_key_image(const crypto::key_image& img); + virtual bool has_key_image(const crypto::key_image& img) const; virtual uint64_t add_block( const block& blk , const size_t& block_size @@ -217,7 +217,7 @@ private: * * @return the resultant tx output */ - tx_out output_from_blob(const blobdata& blob); + tx_out output_from_blob(const blobdata& blob) const; /** * @brief get the global index of the index-th output of the given amount @@ -227,9 +227,9 @@ private: * * @return the global index of the desired output */ - uint64_t get_output_global_index(const uint64_t& amount, const uint64_t& index); + uint64_t get_output_global_index(const uint64_t& amount, const uint64_t& index) const; - void check_open(); + void check_open() const; MDB_env* m_env; diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 647b9405d..b5c4f9ca4 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -129,14 +129,14 @@ void Blockchain::serialize(archive_t & ar, const unsigned int version) "m_current_block_cumul_sz_limit: " << m_current_block_cumul_sz_limit); } //------------------------------------------------------------------ -bool Blockchain::have_tx(const crypto::hash &id) +bool Blockchain::have_tx(const crypto::hash &id) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); return m_db->tx_exists(id); } //------------------------------------------------------------------ -bool Blockchain::have_tx_keyimg_as_spent(const crypto::key_image &key_im) +bool Blockchain::have_tx_keyimg_as_spent(const crypto::key_image &key_im) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -147,7 +147,7 @@ bool Blockchain::have_tx_keyimg_as_spent(const crypto::key_image &key_im) // and collects the public key for each from the transaction it was included in // via the visitor passed to it. template<class visitor_t> -bool Blockchain::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height) +bool Blockchain::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -217,7 +217,7 @@ bool Blockchain::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, vi return true; } //------------------------------------------------------------------ -uint64_t Blockchain::get_current_blockchain_height() +uint64_t Blockchain::get_current_blockchain_height() const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -465,7 +465,7 @@ bool Blockchain::purge_transaction_keyimages_from_blockchain(const transaction& return true; } //------------------------------------------------------------------ -crypto::hash Blockchain::get_tail_id(uint64_t& height) +crypto::hash Blockchain::get_tail_id(uint64_t& height) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -473,7 +473,7 @@ crypto::hash Blockchain::get_tail_id(uint64_t& height) return get_tail_id(); } //------------------------------------------------------------------ -crypto::hash Blockchain::get_tail_id() +crypto::hash Blockchain::get_tail_id() const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -492,7 +492,7 @@ crypto::hash Blockchain::get_tail_id() * powers of 2 less recent from there, so 13, 17, 25, etc... * */ -bool Blockchain::get_short_chain_history(std::list<crypto::hash>& ids) +bool Blockchain::get_short_chain_history(std::list<crypto::hash>& ids) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -533,7 +533,7 @@ bool Blockchain::get_short_chain_history(std::list<crypto::hash>& ids) return true; } //------------------------------------------------------------------ -crypto::hash Blockchain::get_block_id_by_height(uint64_t height) +crypto::hash Blockchain::get_block_id_by_height(uint64_t height) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -557,7 +557,7 @@ crypto::hash Blockchain::get_block_id_by_height(uint64_t height) return null_hash; } //------------------------------------------------------------------ -bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk) +bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -593,7 +593,7 @@ bool Blockchain::get_block_by_hash(const crypto::hash &h, block &blk) //------------------------------------------------------------------ //FIXME: this function does not seem to be called from anywhere, but // if it ever is, should probably change std::list for std::vector -void Blockchain::get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid) +void Blockchain::get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -603,10 +603,10 @@ void Blockchain::get_all_known_block_ids(std::list<crypto::hash> &main, std::lis main.push_back(a); } - BOOST_FOREACH(blocks_ext_by_hash::value_type &v, m_alternative_chains) + BOOST_FOREACH(const blocks_ext_by_hash::value_type &v, m_alternative_chains) alt.push_back(v.first); - BOOST_FOREACH(blocks_ext_by_hash::value_type &v, m_invalid_blocks) + BOOST_FOREACH(const blocks_ext_by_hash::value_type &v, m_invalid_blocks) invalid.push_back(v.first); } //------------------------------------------------------------------ @@ -614,7 +614,7 @@ void Blockchain::get_all_known_block_ids(std::list<crypto::hash> &main, std::lis // last DIFFICULTY_BLOCKS_COUNT blocks and passes them to next_difficulty, // returning the result of that call. Ignores the genesis block, and can use // less blocks than desired if there aren't enough. -difficulty_type Blockchain::get_difficulty_for_next_block() +difficulty_type Blockchain::get_difficulty_for_next_block() const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -760,7 +760,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash:: //------------------------------------------------------------------ // This function calculates the difficulty target for the block being added to // an alternate chain. -difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei) +difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei) const { LOG_PRINT_L3("Blockchain::" << __func__); std::vector<uint64_t> timestamps; @@ -887,7 +887,7 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl //------------------------------------------------------------------ // get the block sizes of the last <count> blocks, starting at <from_height> // and return by reference <sz>. -void Blockchain::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) +void Blockchain::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -905,7 +905,7 @@ void Blockchain::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) } } //------------------------------------------------------------------ -uint64_t Blockchain::get_current_cumulative_blocksize_limit() +uint64_t Blockchain::get_current_cumulative_blocksize_limit() const { LOG_PRINT_L3("Blockchain::" << __func__); return m_current_block_cumul_sz_limit; @@ -922,7 +922,7 @@ uint64_t Blockchain::get_current_cumulative_blocksize_limit() // in a lot of places. That flag is not referenced in any of the code // nor any of the makefiles, howeve. Need to look into whether or not it's // necessary at all. -bool Blockchain::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce) +bool Blockchain::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce) const { LOG_PRINT_L3("Blockchain::" << __func__); size_t median_size; @@ -1250,7 +1250,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) +bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1272,7 +1272,7 @@ bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block return true; } //------------------------------------------------------------------ -bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) +bool Blockchain::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1323,7 +1323,7 @@ bool Blockchain::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NO return true; } //------------------------------------------------------------------ -bool Blockchain::get_alternative_blocks(std::list<block>& blocks) +bool Blockchain::get_alternative_blocks(std::list<block>& blocks) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1335,7 +1335,7 @@ bool Blockchain::get_alternative_blocks(std::list<block>& blocks) return true; } //------------------------------------------------------------------ -size_t Blockchain::get_alternative_blocks_count() +size_t Blockchain::get_alternative_blocks_count() const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1344,7 +1344,7 @@ size_t Blockchain::get_alternative_blocks_count() //------------------------------------------------------------------ // This function adds the output specified by <amount, i> to the result_outs container // unlocked and other such checks should be done by here. -void Blockchain::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) +void Blockchain::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1358,7 +1358,7 @@ void Blockchain::add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_A // with the requested mixins. // TODO: figure out why this returns boolean / if we should be returning false // in some cases -bool Blockchain::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) +bool Blockchain::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) const { LOG_PRINT_L3("Blockchain::" << __func__); srand(static_cast<unsigned int>(time(NULL))); @@ -1431,7 +1431,7 @@ bool Blockchain::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUT // This function takes a list of block hashes from another node // on the network to find where the split point is between us and them. // This is used to see what to send another node that needs to sync. -bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset) +bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1486,7 +1486,8 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc } // if split_height remains 0, we didn't have any but the genesis block in common - if(split_height == 0) + // which is only fine if the blocks just have the genesis block + if(split_height == 0 && qblock_ids.size() > 1) { LOG_ERROR("Ours and foreign blockchain have only genesis block in common... o.O"); return false; @@ -1497,7 +1498,7 @@ bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qbloc return true; } //------------------------------------------------------------------ -uint64_t Blockchain::block_difficulty(uint64_t i) +uint64_t Blockchain::block_difficulty(uint64_t i) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1513,7 +1514,7 @@ uint64_t Blockchain::block_difficulty(uint64_t i) } //------------------------------------------------------------------ template<class t_ids_container, class t_blocks_container, class t_missed_container> -bool Blockchain::get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) +bool Blockchain::get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1537,7 +1538,7 @@ bool Blockchain::get_blocks(const t_ids_container& block_ids, t_blocks_container } //------------------------------------------------------------------ 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) +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); @@ -1618,7 +1619,7 @@ void Blockchain::print_blockchain_outs(const std::string& file) // Find the split point between us and foreign blockchain and return // (by reference) the most recent common block hash along with up to // BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT additional (more recent) hashes. -bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) +bool Blockchain::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1642,7 +1643,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) +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 { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1696,7 +1697,7 @@ bool Blockchain::add_block_as_invalid(const block_extended_info& bei, const cryp return true; } //------------------------------------------------------------------ -bool Blockchain::have_block(const crypto::hash& id) +bool Blockchain::have_block(const crypto::hash& id) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1720,7 +1721,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, block_verification_ return handle_block_to_main_chain(bl, id, bvc); } //------------------------------------------------------------------ -size_t Blockchain::get_total_transactions() +size_t Blockchain::get_total_transactions() const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1733,7 +1734,7 @@ size_t Blockchain::get_total_transactions() // This container should be managed by the code that validates blocks so we don't // have to store the used keys in a given block in the permanent storage only to // remove them later if the block fails validation. -bool Blockchain::check_for_double_spend(const transaction& tx, key_images_container& keys_this_block) +bool Blockchain::check_for_double_spend(const transaction& tx, key_images_container& keys_this_block) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1782,7 +1783,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) +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); @@ -1799,7 +1800,7 @@ bool Blockchain::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<u // This function overloads its sister function with // an extra value (hash of highest block that holds an output used as input) // as a return-by-reference. -bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t& max_used_block_height, crypto::hash& max_used_block_id) +bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t& max_used_block_height, crypto::hash& max_used_block_id) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1810,7 +1811,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t& max_used_block return true; } //------------------------------------------------------------------ -bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) +bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) const { LOG_PRINT_L3("Blockchain::" << __func__); BOOST_FOREACH(const txin_v& in, tx.vin) @@ -1825,7 +1826,7 @@ bool Blockchain::have_tx_keyimges_as_spent(const transaction &tx) // This function validates transaction inputs and their keys. Previously // it also performed double spend checking, but that has been moved to its // own function. -bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height) +bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height) const { LOG_PRINT_L3("Blockchain::" << __func__); size_t sig_index = 0; @@ -1863,7 +1864,7 @@ bool Blockchain::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_bloc //------------------------------------------------------------------ // This function checks to see if a tx is unlocked. unlock_time is either // a block index or a unix time. -bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time) +bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time) const { LOG_PRINT_L3("Blockchain::" << __func__); if(unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) @@ -1888,7 +1889,7 @@ bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time) // This function locates all outputs associated with a given input (mixins) // and validates that they exist and are usable. It also checks the ring // signature for each input. -bool Blockchain::check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height) +bool Blockchain::check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1897,8 +1898,8 @@ bool Blockchain::check_tx_input(const txin_to_key& txin, const crypto::hash& tx_ { std::vector<const crypto::public_key *>& m_p_output_keys; std::vector<crypto::public_key >& m_output_keys; - Blockchain& m_bch; - outputs_visitor(std::vector<crypto::public_key >& output_keys, std::vector<const crypto::public_key *>& p_output_keys, Blockchain& bch) : m_output_keys(output_keys), m_p_output_keys(p_output_keys), m_bch(bch) + const Blockchain& m_bch; + outputs_visitor(std::vector<crypto::public_key >& output_keys, std::vector<const crypto::public_key *>& p_output_keys, const Blockchain& bch) : m_output_keys(output_keys), m_p_output_keys(p_output_keys), m_bch(bch) {} bool handle_output(const transaction& tx, const tx_out& out) { @@ -1947,7 +1948,7 @@ bool Blockchain::check_tx_input(const txin_to_key& txin, const crypto::hash& tx_ } //------------------------------------------------------------------ //TODO: Is this intended to do something else? Need to look into the todo there. -uint64_t Blockchain::get_adjusted_time() +uint64_t Blockchain::get_adjusted_time() const { LOG_PRINT_L3("Blockchain::" << __func__); //TODO: add collecting median time @@ -1955,7 +1956,7 @@ uint64_t Blockchain::get_adjusted_time() } //------------------------------------------------------------------ //TODO: revisit, has changed a bit on upstream -bool Blockchain::check_block_timestamp(std::vector<uint64_t>& timestamps, const block& b) +bool Blockchain::check_block_timestamp(std::vector<uint64_t>& timestamps, const block& b) const { LOG_PRINT_L3("Blockchain::" << __func__); uint64_t median_ts = epee::misc_utils::median(timestamps); @@ -1976,7 +1977,7 @@ bool Blockchain::check_block_timestamp(std::vector<uint64_t>& timestamps, const // true if the block's timestamp is not less than the timestamp of the // median of the selected blocks // false otherwise -bool Blockchain::check_block_timestamp(const block& b) +bool Blockchain::check_block_timestamp(const block& b) const { LOG_PRINT_L3("Blockchain::" << __func__); if(b.timestamp > get_adjusted_time() + CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT) diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 75a729a09..6ab963ac7 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -87,54 +87,54 @@ namespace cryptonote void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; } //bool push_new_block(); - bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs); - bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks); - bool get_alternative_blocks(std::list<block>& blocks); - size_t get_alternative_blocks_count(); - crypto::hash get_block_id_by_height(uint64_t height); - bool get_block_by_hash(const crypto::hash &h, block &blk); - void get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid); + 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<block>& blocks) const; + bool get_alternative_blocks(std::list<block>& blocks) const; + size_t get_alternative_blocks_count() const; + crypto::hash get_block_id_by_height(uint64_t height) const; + bool get_block_by_hash(const crypto::hash &h, block &blk) const; + void get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid) const; template<class archive_t> void serialize(archive_t & ar, const unsigned int version); - bool have_tx(const crypto::hash &id); - bool have_tx_keyimges_as_spent(const transaction &tx); - bool have_tx_keyimg_as_spent(const crypto::key_image &key_im); + bool have_tx(const crypto::hash &id) const; + bool have_tx_keyimges_as_spent(const transaction &tx) const; + bool have_tx_keyimg_as_spent(const crypto::key_image &key_im) const; template<class visitor_t> - bool scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height = NULL); + bool scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height = NULL) const; - uint64_t get_current_blockchain_height(); - crypto::hash get_tail_id(); - crypto::hash get_tail_id(uint64_t& height); - difficulty_type get_difficulty_for_next_block(); + uint64_t get_current_blockchain_height() const; + crypto::hash get_tail_id() const; + crypto::hash get_tail_id(uint64_t& height) const; + difficulty_type get_difficulty_for_next_block() const; bool add_new_block(const block& bl_, block_verification_context& bvc); bool reset_and_set_genesis_block(const block& b); - bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, const blobdata& ex_nonce); - bool have_block(const crypto::hash& id); - size_t get_total_transactions(); - bool get_short_chain_history(std::list<crypto::hash>& ids); - bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp); - bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset); - 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); + bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, const blobdata& ex_nonce) const; + bool have_block(const crypto::hash& id) const; + size_t get_total_transactions() const; + bool get_short_chain_history(std::list<crypto::hash>& ids) const; + bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const; + bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset) 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 handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp); bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res); - bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res); - bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs); + bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) const; + bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const; bool store_blockchain(); - bool check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height = NULL); - bool check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height = NULL); - bool check_tx_inputs(const transaction& tx, uint64_t& pmax_used_block_height, crypto::hash& max_used_block_id); - uint64_t get_current_cumulative_blocksize_limit(); - bool is_storing_blockchain(){return m_is_blockchain_storing;} - uint64_t block_difficulty(uint64_t i); + bool check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height = NULL) const; + bool check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height = NULL) const; + bool check_tx_inputs(const transaction& tx, uint64_t& pmax_used_block_height, crypto::hash& max_used_block_id) const; + uint64_t get_current_cumulative_blocksize_limit() const; + bool is_storing_blockchain()const{return m_is_blockchain_storing;} + uint64_t block_difficulty(uint64_t i) const; template<class t_ids_container, class t_blocks_container, class t_missed_container> - bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs); + bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) 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); + bool get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const; //debug functions void print_blockchain(uint64_t start_index, uint64_t end_index); @@ -157,7 +157,7 @@ namespace cryptonote BlockchainDB* m_db; tx_memory_pool& m_tx_pool; - epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock + mutable epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock // main chain blocks_container m_blocks; // height -> block_extended_info @@ -190,7 +190,7 @@ namespace cryptonote bool handle_block_to_main_chain(const block& bl, block_verification_context& bvc); bool handle_block_to_main_chain(const block& bl, const crypto::hash& id, block_verification_context& bvc); bool handle_alternative_block(const block& b, const crypto::hash& id, block_verification_context& bvc); - difficulty_type get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei); + difficulty_type get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei) const; bool prevalidate_miner_transaction(const block& b, uint64_t height); bool validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins); bool validate_transaction(const block& b, uint64_t height, const transaction& tx); @@ -198,18 +198,18 @@ namespace cryptonote bool add_transaction_from_block(const transaction& tx, const crypto::hash& tx_id, const crypto::hash& bl_id, uint64_t bl_height); bool push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector<uint64_t>& global_indexes); bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id); - void get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count); - void add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i); - bool is_tx_spendtime_unlocked(uint64_t unlock_time); + void get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) const; + void add_out_to_get_random_outs(COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) const; + bool is_tx_spendtime_unlocked(uint64_t unlock_time) const; bool add_block_as_invalid(const block& bl, const crypto::hash& h); bool add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h); - bool check_block_timestamp(const block& b); - bool check_block_timestamp(std::vector<uint64_t>& timestamps, const block& b); - uint64_t get_adjusted_time(); + bool check_block_timestamp(const block& b) const; + bool check_block_timestamp(std::vector<uint64_t>& timestamps, const block& b) const; + uint64_t get_adjusted_time() const; bool complete_timestamps_vector(uint64_t start_height, std::vector<uint64_t>& timestamps); bool update_next_cumulative_size_limit(); - bool check_for_double_spend(const transaction& tx, key_images_container& keys_this_block); + bool check_for_double_spend(const transaction& tx, key_images_container& keys_this_block) const; }; diff --git a/src/cryptonote_core/blockchain_db.h b/src/cryptonote_core/blockchain_db.h index 3418b946b..b9ea79f01 100644 --- a/src/cryptonote_core/blockchain_db.h +++ b/src/cryptonote_core/blockchain_db.h @@ -139,15 +139,16 @@ typedef std::pair<crypto::hash, uint64_t> tx_out_index; /*********************************** * Exception Definitions ***********************************/ -class DB_ERROR : public std::exception +class DB_EXCEPTION : public std::exception { private: std::string m; - public: - DB_ERROR() : m("Generic DB Error") { } - DB_ERROR(const char* s) : m(s) { } - virtual ~DB_ERROR() { } + protected: + DB_EXCEPTION(const char *s) : m(s) { } + + public: + virtual ~DB_EXCEPTION() { } const char* what() const throw() { @@ -155,196 +156,95 @@ class DB_ERROR : public std::exception } }; -class DB_OPEN_FAILURE : public std::exception +class DB_ERROR : public DB_EXCEPTION { - private: - std::string m; public: - DB_OPEN_FAILURE() : m("Failed to open the db") { } - DB_OPEN_FAILURE(const char* s) : m(s) { } - - virtual ~DB_OPEN_FAILURE() { } - - const char* what() const throw() - { - return m.c_str(); - } + DB_ERROR() : DB_EXCEPTION("Generic DB Error") { } + DB_ERROR(const char* s) : DB_EXCEPTION(s) { } }; -class DB_CREATE_FAILURE : public std::exception +class DB_OPEN_FAILURE : public DB_EXCEPTION { - private: - std::string m; public: - DB_CREATE_FAILURE() : m("Failed to create the db") { } - DB_CREATE_FAILURE(const char* s) : m(s) { } - - virtual ~DB_CREATE_FAILURE() { } - - const char* what() const throw() - { - return m.c_str(); - } + DB_OPEN_FAILURE() : DB_EXCEPTION("Failed to open the db") { } + DB_OPEN_FAILURE(const char* s) : DB_EXCEPTION(s) { } }; -class DB_SYNC_FAILURE : public std::exception +class DB_CREATE_FAILURE : public DB_EXCEPTION { - private: - std::string m; public: - DB_SYNC_FAILURE() : m("Failed to sync the db") { } - DB_SYNC_FAILURE(const char* s) : m(s) { } - - virtual ~DB_SYNC_FAILURE() { } - - const char* what() const throw() - { - return m.c_str(); - } + DB_CREATE_FAILURE() : DB_EXCEPTION("Failed to create the db") { } + DB_CREATE_FAILURE(const char* s) : DB_EXCEPTION(s) { } }; -class BLOCK_DNE : public std::exception +class DB_SYNC_FAILURE : public DB_EXCEPTION { - private: - std::string m; public: - BLOCK_DNE() : m("The block requested does not exist") { } - BLOCK_DNE(const char* s) : m(s) { } - - virtual ~BLOCK_DNE() { } - - const char* what() const throw() - { - return m.c_str(); - } + DB_SYNC_FAILURE() : DB_EXCEPTION("Failed to sync the db") { } + DB_SYNC_FAILURE(const char* s) : DB_EXCEPTION(s) { } }; -class BLOCK_PARENT_DNE : public std::exception +class BLOCK_DNE : public DB_EXCEPTION { - private: - std::string m; public: - BLOCK_PARENT_DNE() : m("The parent of the block does not exist") { } - BLOCK_PARENT_DNE(const char* s) : m(s) { } - - virtual ~BLOCK_PARENT_DNE() { } - - const char* what() const throw() - { - return m.c_str(); - } + BLOCK_DNE() : DB_EXCEPTION("The block requested does not exist") { } + BLOCK_DNE(const char* s) : DB_EXCEPTION(s) { } }; -class BLOCK_EXISTS : public std::exception +class BLOCK_PARENT_DNE : public DB_EXCEPTION { - private: - std::string m; public: - BLOCK_EXISTS() : m("The block to be added already exists!") { } - BLOCK_EXISTS(const char* s) : m(s) { } - - virtual ~BLOCK_EXISTS() { } - - const char* what() const throw() - { - return m.c_str(); - } + BLOCK_PARENT_DNE() : DB_EXCEPTION("The parent of the block does not exist") { } + BLOCK_PARENT_DNE(const char* s) : DB_EXCEPTION(s) { } }; -class BLOCK_INVALID : public std::exception +class BLOCK_EXISTS : public DB_EXCEPTION { - private: - std::string m; public: - BLOCK_INVALID() : m("The block to be added did not pass validation!") { } - BLOCK_INVALID(const char* s) : m(s) { } - - virtual ~BLOCK_INVALID() { } - - const char* what() const throw() - { - return m.c_str(); - } + BLOCK_EXISTS() : DB_EXCEPTION("The block to be added already exists!") { } + BLOCK_EXISTS(const char* s) : DB_EXCEPTION(s) { } }; -class TX_DNE : public std::exception +class BLOCK_INVALID : public DB_EXCEPTION { - private: - std::string m; public: - TX_DNE() : m("The transaction requested does not exist") { } - TX_DNE(const char* s) : m(s) { } - - virtual ~TX_DNE() { } - - const char* what() const throw() - { - return m.c_str(); - } + BLOCK_INVALID() : DB_EXCEPTION("The block to be added did not pass validation!") { } + BLOCK_INVALID(const char* s) : DB_EXCEPTION(s) { } }; -class TX_EXISTS : public std::exception +class TX_DNE : public DB_EXCEPTION { - private: - std::string m; public: - TX_EXISTS() : m("The transaction to be added already exists!") { } - TX_EXISTS(const char* s) : m(s) { } - - virtual ~TX_EXISTS() { } - - const char* what() const throw() - { - return m.c_str(); - } + TX_DNE() : DB_EXCEPTION("The transaction requested does not exist") { } + TX_DNE(const char* s) : DB_EXCEPTION(s) { } }; -class OUTPUT_DNE : public std::exception +class TX_EXISTS : public DB_EXCEPTION { - private: - std::string m; public: - OUTPUT_DNE() : m("The output requested does not exist!") { } - OUTPUT_DNE(const char* s) : m(s) { } - - virtual ~OUTPUT_DNE() { } - - const char* what() const throw() - { - return m.c_str(); - } + TX_EXISTS() : DB_EXCEPTION("The transaction to be added already exists!") { } + TX_EXISTS(const char* s) : DB_EXCEPTION(s) { } }; -class OUTPUT_EXISTS : public std::exception +class OUTPUT_DNE : public DB_EXCEPTION { - private: - std::string m; public: - OUTPUT_EXISTS() : m("The output to be added already exists!") { } - OUTPUT_EXISTS(const char* s) : m(s) { } - - virtual ~OUTPUT_EXISTS() { } - - const char* what() const throw() - { - return m.c_str(); - } + OUTPUT_DNE() : DB_EXCEPTION("The output requested does not exist!") { } + OUTPUT_DNE(const char* s) : DB_EXCEPTION(s) { } }; -class KEY_IMAGE_EXISTS : public std::exception +class OUTPUT_EXISTS : public DB_EXCEPTION { - private: - std::string m; public: - KEY_IMAGE_EXISTS() : m("The spent key image to be added already exists!") { } - KEY_IMAGE_EXISTS(const char* s) : m(s) { } - - virtual ~KEY_IMAGE_EXISTS() { } + OUTPUT_EXISTS() : DB_EXCEPTION("The output to be added already exists!") { } + OUTPUT_EXISTS(const char* s) : DB_EXCEPTION(s) { } +}; - const char* what() const throw() - { - return m.c_str(); - } +class KEY_IMAGE_EXISTS : public DB_EXCEPTION +{ + public: + KEY_IMAGE_EXISTS() : DB_EXCEPTION("The spent key image to be added already exists!") { } + KEY_IMAGE_EXISTS(const char* s) : DB_EXCEPTION(s) { } }; /*********************************** @@ -423,7 +323,7 @@ public: virtual void reset() = 0; // get all files used by this db (if any) - virtual std::vector<std::string> get_filenames() = 0; + virtual std::vector<std::string> get_filenames() const = 0; // FIXME: these are just for functionality mocking, need to implement @@ -447,59 +347,59 @@ public: ); // return true if a block with hash <h> exists in the blockchain - virtual bool block_exists(const crypto::hash& h) = 0; + virtual bool block_exists(const crypto::hash& h) const = 0; // return block with hash <h> - virtual block get_block(const crypto::hash& h) = 0; + virtual block get_block(const crypto::hash& h) const = 0; // return the height of the block with hash <h> on the blockchain, // throw if it doesn't exist - virtual uint64_t get_block_height(const crypto::hash& h) = 0; + virtual uint64_t get_block_height(const crypto::hash& h) const = 0; // return header for block with hash <h> - virtual block_header get_block_header(const crypto::hash& h) = 0; + virtual block_header get_block_header(const crypto::hash& h) const = 0; // return block at height <height> - virtual block get_block_from_height(const uint64_t& height) = 0; + virtual block get_block_from_height(const uint64_t& height) const = 0; // return timestamp of block at height <height> - virtual uint64_t get_block_timestamp(const uint64_t& height) = 0; + virtual uint64_t get_block_timestamp(const uint64_t& height) const = 0; // return timestamp of most recent block - virtual uint64_t get_top_block_timestamp() = 0; + virtual uint64_t get_top_block_timestamp() const = 0; // return block size of block at height <height> - virtual size_t get_block_size(const uint64_t& height) = 0; + virtual size_t get_block_size(const uint64_t& height) const = 0; // return cumulative difficulty up to and including block at height <height> - virtual difficulty_type get_block_cumulative_difficulty(const uint64_t& height) = 0; + virtual difficulty_type get_block_cumulative_difficulty(const uint64_t& height) const = 0; // return difficulty of block at height <height> - virtual difficulty_type get_block_difficulty(const uint64_t& height) = 0; + virtual difficulty_type get_block_difficulty(const uint64_t& height) const = 0; // return number of coins generated up to and including block at height <height> - virtual uint64_t get_block_already_generated_coins(const uint64_t& height) = 0; + virtual uint64_t get_block_already_generated_coins(const uint64_t& height) const = 0; // return hash of block at height <height> - virtual crypto::hash get_block_hash_from_height(const uint64_t& height) = 0; + virtual crypto::hash get_block_hash_from_height(const uint64_t& height) const = 0; // return vector of blocks in range <h1,h2> of height (inclusively) - virtual std::vector<block> get_blocks_range(const uint64_t& h1, const uint64_t& h2) = 0; + virtual std::vector<block> get_blocks_range(const uint64_t& h1, const uint64_t& h2) const = 0; // return vector of block hashes in range <h1, h2> of height (inclusively) - virtual std::vector<crypto::hash> get_hashes_range(const uint64_t& h1, const uint64_t& h2) = 0; + virtual std::vector<crypto::hash> get_hashes_range(const uint64_t& h1, const uint64_t& h2) const = 0; // return the hash of the top block on the chain - virtual crypto::hash top_block_hash() = 0; + virtual crypto::hash top_block_hash() const = 0; // return the block at the top of the blockchain - virtual block get_top_block() = 0; + virtual block get_top_block() const = 0; // return the index of the top block on the chain // NOTE: for convenience using heights as indices, this is not the total // size of the blockchain, but rather the index of the top block. As the // chain is 0-indexed, the total size will be height() + 1. - virtual uint64_t height() = 0; + virtual uint64_t height() const = 0; // pops the top block off the blockchain. // Returns by reference the popped block and its associated transactions @@ -512,48 +412,48 @@ public: // return true if a transaction with hash <h> exists - virtual bool tx_exists(const crypto::hash& h) = 0; + virtual bool tx_exists(const crypto::hash& h) const = 0; // return unlock time of tx with hash <h> - virtual uint64_t get_tx_unlock_time(const crypto::hash& h) = 0; + virtual uint64_t get_tx_unlock_time(const crypto::hash& h) const = 0; // return tx with hash <h> // throw if no such tx exists - virtual transaction get_tx(const crypto::hash& h) = 0; + virtual transaction get_tx(const crypto::hash& h) const = 0; // returns the total number of transactions in all blocks - virtual uint64_t get_tx_count() = 0; + virtual uint64_t get_tx_count() const = 0; // return list of tx with hashes <hlist>. // TODO: decide if a missing hash means return empty list // or just skip that hash - virtual std::vector<transaction> get_tx_list(const std::vector<crypto::hash>& hlist) = 0; + virtual std::vector<transaction> get_tx_list(const std::vector<crypto::hash>& hlist) const = 0; // returns height of block that contains transaction with hash <h> - virtual uint64_t get_tx_block_height(const crypto::hash& h) = 0; + virtual uint64_t get_tx_block_height(const crypto::hash& h) const = 0; // return global output index of a random output of amount <amount> - virtual uint64_t get_random_output(const uint64_t& amount) = 0; + virtual uint64_t get_random_output(const uint64_t& amount) const = 0; // returns the total number of outputs of amount <amount> - virtual uint64_t get_num_outputs(const uint64_t& amount) = 0; + virtual uint64_t get_num_outputs(const uint64_t& amount) const = 0; // return public key for output with global output amount <amount> and index <index> - virtual crypto::public_key get_output_key(const uint64_t& amount, const uint64_t& index) = 0; + virtual crypto::public_key get_output_key(const uint64_t& amount, const uint64_t& index) const = 0; // returns the output indexed by <index> in the transaction with hash <h> - virtual tx_out get_output(const crypto::hash& h, const uint64_t& index) = 0; + virtual tx_out get_output(const crypto::hash& h, const uint64_t& index) const = 0; // returns the transaction-local reference for the output with <amount> at <index> // return type is pair of tx hash and index - virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) = 0; + virtual tx_out_index get_output_tx_and_index(const uint64_t& amount, const uint64_t& index) const = 0; // return a vector of indices corresponding to the global output index for // each output in the transaction with hash <h> - virtual std::vector<uint64_t> get_tx_output_indices(const crypto::hash& h) = 0; + virtual std::vector<uint64_t> get_tx_output_indices(const crypto::hash& h) const = 0; // returns true if key image <img> is present in spent key images storage - virtual bool has_key_image(const crypto::key_image& img) = 0; + virtual bool has_key_image(const crypto::key_image& img) const = 0; }; // class BlockchainDB diff --git a/src/cryptonote_core/blockchain_storage.cpp b/src/cryptonote_core/blockchain_storage.cpp index e40eb6a0f..11bd1f2ac 100644 --- a/src/cryptonote_core/blockchain_storage.cpp +++ b/src/cryptonote_core/blockchain_storage.cpp @@ -55,19 +55,19 @@ using namespace cryptonote; DISABLE_VS_WARNINGS(4267) //------------------------------------------------------------------ -bool blockchain_storage::have_tx(const crypto::hash &id) +bool blockchain_storage::have_tx(const crypto::hash &id) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); return m_transactions.find(id) != m_transactions.end(); } //------------------------------------------------------------------ -bool blockchain_storage::have_tx_keyimg_as_spent(const crypto::key_image &key_im) +bool blockchain_storage::have_tx_keyimg_as_spent(const crypto::key_image &key_im) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); return m_spent_keys.find(key_im) != m_spent_keys.end(); } //------------------------------------------------------------------ -transaction *blockchain_storage::get_tx(const crypto::hash &id) +const transaction *blockchain_storage::get_tx(const crypto::hash &id) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); auto it = m_transactions.find(id); @@ -77,7 +77,7 @@ transaction *blockchain_storage::get_tx(const crypto::hash &id) return &it->second.tx; } //------------------------------------------------------------------ -uint64_t blockchain_storage::get_current_blockchain_height() +uint64_t blockchain_storage::get_current_blockchain_height() const { CRITICAL_REGION_LOCAL(m_blockchain_lock); return m_blocks.size(); @@ -113,24 +113,14 @@ bool blockchain_storage::init(const std::string& config_folder, bool testnet) else { LOG_PRINT_L0("Can't load blockchain storage from file, generating genesis block."); - block bl = boost::value_initialized<block>(); - block_verification_context bvc = boost::value_initialized<block_verification_context>(); - if (testnet) - { - generate_genesis_block(bl, config::testnet::GENESIS_TX, config::testnet::GENESIS_NONCE); - } - else - { - generate_genesis_block(bl, config::GENESIS_TX, config::GENESIS_NONCE); - } - add_new_block(bl, bvc); - CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed && bvc.m_added_to_main_chain, false, "Failed to add genesis block to blockchain"); + if (!store_genesis_block(testnet, true)) + return false; } if(!m_blocks.size()) { LOG_PRINT_L0("Blockchain not loaded, generating genesis block."); - if (!store_genesis_block(testnet)) { + if (!store_genesis_block(testnet, false)) { return false; } } else { @@ -159,7 +149,7 @@ bool blockchain_storage::init(const std::string& config_folder, bool testnet) return true; } //------------------------------------------------------------------ -bool blockchain_storage::store_genesis_block(bool testnet) { +bool blockchain_storage::store_genesis_block(bool testnet, bool check_added) { block bl = ::boost::value_initialized<block>(); block_verification_context bvc = boost::value_initialized<block_verification_context>(); @@ -173,7 +163,7 @@ bool blockchain_storage::store_genesis_block(bool testnet) { } add_new_block(bl, bvc); - CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false, "Failed to add genesis block to blockchain"); + CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed && (bvc.m_added_to_main_chain || !check_added), false, "Failed to add genesis block to blockchain"); return true; } //------------------------------------------------------------------ @@ -333,14 +323,14 @@ bool blockchain_storage::purge_block_data_from_blockchain(const block& bl, size_ return res; } //------------------------------------------------------------------ -crypto::hash blockchain_storage::get_tail_id(uint64_t& height) +crypto::hash blockchain_storage::get_tail_id(uint64_t& height) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); height = get_current_blockchain_height()-1; return get_tail_id(); } //------------------------------------------------------------------ -crypto::hash blockchain_storage::get_tail_id() +crypto::hash blockchain_storage::get_tail_id() const { CRITICAL_REGION_LOCAL(m_blockchain_lock); crypto::hash id = null_hash; @@ -351,7 +341,7 @@ crypto::hash blockchain_storage::get_tail_id() return id; } //------------------------------------------------------------------ -bool blockchain_storage::get_short_chain_history(std::list<crypto::hash>& ids) +bool blockchain_storage::get_short_chain_history(std::list<crypto::hash>& ids) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); size_t i = 0; @@ -381,7 +371,7 @@ bool blockchain_storage::get_short_chain_history(std::list<crypto::hash>& ids) return true; } //------------------------------------------------------------------ -crypto::hash blockchain_storage::get_block_id_by_height(uint64_t height) +crypto::hash blockchain_storage::get_block_id_by_height(uint64_t height) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(height >= m_blocks.size()) @@ -390,7 +380,7 @@ crypto::hash blockchain_storage::get_block_id_by_height(uint64_t height) return get_block_hash(m_blocks[height].bl); } //------------------------------------------------------------------ -bool blockchain_storage::get_block_by_hash(const crypto::hash &h, block &blk) { +bool blockchain_storage::get_block_by_hash(const crypto::hash &h, block &blk) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); // try to find block in main chain @@ -410,20 +400,20 @@ bool blockchain_storage::get_block_by_hash(const crypto::hash &h, block &blk) { return false; } //------------------------------------------------------------------ -void blockchain_storage::get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid) { +void blockchain_storage::get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); - BOOST_FOREACH(blocks_by_id_index::value_type &v, m_blocks_index) + BOOST_FOREACH(const blocks_by_id_index::value_type &v, m_blocks_index) main.push_back(v.first); - BOOST_FOREACH(blocks_ext_by_hash::value_type &v, m_alternative_chains) + BOOST_FOREACH(const blocks_ext_by_hash::value_type &v, m_alternative_chains) alt.push_back(v.first); - BOOST_FOREACH(blocks_ext_by_hash::value_type &v, m_invalid_blocks) + BOOST_FOREACH(const blocks_ext_by_hash::value_type &v, m_invalid_blocks) invalid.push_back(v.first); } //------------------------------------------------------------------ -difficulty_type blockchain_storage::get_difficulty_for_next_block() +difficulty_type blockchain_storage::get_difficulty_for_next_block() const { CRITICAL_REGION_LOCAL(m_blockchain_lock); std::vector<uint64_t> timestamps; @@ -535,7 +525,7 @@ bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_b return true; } //------------------------------------------------------------------ -difficulty_type blockchain_storage::get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei) +difficulty_type blockchain_storage::get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei) const { std::vector<uint64_t> timestamps; std::vector<difficulty_type> commulative_difficulties; @@ -580,7 +570,7 @@ difficulty_type blockchain_storage::get_next_difficulty_for_alternative_chain(co return next_difficulty(timestamps, commulative_difficulties); } //------------------------------------------------------------------ -bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t height) +bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t height) const { CHECK_AND_ASSERT_MES(b.miner_tx.vin.size() == 1, false, "coinbase transaction in the block has no inputs"); CHECK_AND_ASSERT_MES(b.miner_tx.vin[0].type() == typeid(txin_gen), false, "coinbase transaction in the block has the wrong type"); @@ -603,7 +593,7 @@ bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t return true; } //------------------------------------------------------------------ -bool blockchain_storage::validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins) +bool blockchain_storage::validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins) const { //validate reward uint64_t money_in_use = 0; @@ -630,7 +620,7 @@ bool blockchain_storage::validate_miner_transaction(const block& b, size_t cumul return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_backward_blocks_sizes(size_t from_height, std::vector<size_t>& sz, size_t count) +bool blockchain_storage::get_backward_blocks_sizes(size_t from_height, std::vector<size_t>& sz, size_t count) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); CHECK_AND_ASSERT_MES(from_height < m_blocks.size(), false, "Internal error: get_backward_blocks_sizes called with from_height=" << from_height << ", blockchain height = " << m_blocks.size()); @@ -642,7 +632,7 @@ bool blockchain_storage::get_backward_blocks_sizes(size_t from_height, std::vect return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) +bool blockchain_storage::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(!m_blocks.size()) @@ -650,12 +640,12 @@ bool blockchain_storage::get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t return get_backward_blocks_sizes(m_blocks.size() -1, sz, count); } //------------------------------------------------------------------ -uint64_t blockchain_storage::get_current_comulative_blocksize_limit() +uint64_t blockchain_storage::get_current_comulative_blocksize_limit() const { return m_current_block_cumul_sz_limit; } //------------------------------------------------------------------ -bool blockchain_storage::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce) +bool blockchain_storage::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce) const { size_t median_size; uint64_t already_generated_coins; @@ -774,7 +764,7 @@ bool blockchain_storage::create_block_template(block& b, const account_public_ad return false; } //------------------------------------------------------------------ -bool blockchain_storage::complete_timestamps_vector(uint64_t start_top_height, std::vector<uint64_t>& timestamps) +bool blockchain_storage::complete_timestamps_vector(uint64_t start_top_height, std::vector<uint64_t>& timestamps) const { if(timestamps.size() >= BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW) @@ -939,7 +929,7 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto:: return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) +bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(start_offset >= m_blocks.size()) @@ -955,7 +945,7 @@ bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::li return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) +bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(start_offset >= m_blocks.size()) @@ -999,7 +989,7 @@ bool blockchain_storage::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_alternative_blocks(std::list<block>& blocks) +bool blockchain_storage::get_alternative_blocks(std::list<block>& blocks) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1010,21 +1000,21 @@ bool blockchain_storage::get_alternative_blocks(std::list<block>& blocks) return true; } //------------------------------------------------------------------ -size_t blockchain_storage::get_alternative_blocks_count() +size_t blockchain_storage::get_alternative_blocks_count() const { CRITICAL_REGION_LOCAL(m_blockchain_lock); return m_alternative_chains.size(); } //------------------------------------------------------------------ -bool blockchain_storage::add_out_to_get_random_outs(std::vector<std::pair<crypto::hash, size_t> >& amount_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) +bool blockchain_storage::add_out_to_get_random_outs(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); - transactions_container::iterator tx_it = m_transactions.find(amount_outs[i].first); + transactions_container::const_iterator tx_it = m_transactions.find(amount_outs[i].first); CHECK_AND_ASSERT_MES(tx_it != m_transactions.end(), false, "internal error: transaction with id " << amount_outs[i].first << ENDL << ", used in mounts global index for amount=" << amount << ": i=" << i << "not found in transactions index"); CHECK_AND_ASSERT_MES(tx_it->second.tx.vout.size() > amount_outs[i].second, false, "internal error: in global outs index, transaction out index=" << amount_outs[i].second << " more than transaction outputs = " << tx_it->second.tx.vout.size() << ", for tx id = " << amount_outs[i].first); - transaction& tx = tx_it->second.tx; + const transaction& tx = tx_it->second.tx; CHECK_AND_ASSERT_MES(tx.vout[amount_outs[i].second].target.type() == typeid(txout_to_key), false, "unknown tx out type"); //check if transaction is unlocked @@ -1037,7 +1027,7 @@ bool blockchain_storage::add_out_to_get_random_outs(std::vector<std::pair<crypto return true; } //------------------------------------------------------------------ -size_t blockchain_storage::find_end_of_allowed_index(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs) +size_t blockchain_storage::find_end_of_allowed_index(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(!amount_outs.size()) @@ -1046,7 +1036,7 @@ size_t blockchain_storage::find_end_of_allowed_index(const std::vector<std::pair do { --i; - transactions_container::iterator it = m_transactions.find(amount_outs[i].first); + transactions_container::const_iterator it = m_transactions.find(amount_outs[i].first); CHECK_AND_ASSERT_MES(it != m_transactions.end(), 0, "internal error: failed to find transaction from outputs index with tx_id=" << amount_outs[i].first); if(it->second.m_keeper_block_height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW <= get_current_blockchain_height() ) return i+1; @@ -1054,7 +1044,7 @@ size_t blockchain_storage::find_end_of_allowed_index(const std::vector<std::pair return 0; } //------------------------------------------------------------------ -bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) +bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); BOOST_FOREACH(uint64_t amount, req.amounts) @@ -1067,7 +1057,7 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO LOG_PRINT_L1("COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS: not outs for amount " << amount << ", wallet should use some real outs when it lookup for some mix, so, at least one out for this amount should exist"); continue;//actually this is strange situation, wallet should use some real outs when it lookup for some mix, so, at least one out for this amount should exist } - std::vector<std::pair<crypto::hash, size_t> >& amount_outs = it->second; + const std::vector<std::pair<crypto::hash, size_t> >& amount_outs = it->second; //it is not good idea to use top fresh outs, because it increases possibility of transaction canceling on split //lets find upper bound of not fresh outs size_t up_index_limit = find_end_of_allowed_index(amount_outs); @@ -1096,7 +1086,7 @@ bool blockchain_storage::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDO return true; } //------------------------------------------------------------------ -bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset) +bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -1143,7 +1133,7 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash return true; } //------------------------------------------------------------------ -uint64_t blockchain_storage::block_difficulty(size_t i) +uint64_t blockchain_storage::block_difficulty(size_t i) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); CHECK_AND_ASSERT_MES(i < m_blocks.size(), false, "wrong block index i = " << i << " at blockchain_storage::block_difficulty()"); @@ -1206,7 +1196,7 @@ void blockchain_storage::print_blockchain_outs(const std::string& file) } } //------------------------------------------------------------------ -bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) +bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(!find_blockchain_supplement(qblock_ids, resp.start_height)) @@ -1219,7 +1209,7 @@ bool blockchain_storage::find_blockchain_supplement(const std::list<crypto::hash return true; } //------------------------------------------------------------------ -bool blockchain_storage::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) +bool blockchain_storage::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 { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(req_start_block > 0) { @@ -1258,7 +1248,7 @@ bool blockchain_storage::add_block_as_invalid(const block_extended_info& bei, co return true; } //------------------------------------------------------------------ -bool blockchain_storage::have_block(const crypto::hash& id) +bool blockchain_storage::have_block(const crypto::hash& id) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); if(m_blocks_index.count(id)) @@ -1296,13 +1286,13 @@ bool blockchain_storage::push_transaction_to_global_outs_index(const transaction return true; } //------------------------------------------------------------------ -size_t blockchain_storage::get_total_transactions() +size_t blockchain_storage::get_total_transactions() const { CRITICAL_REGION_LOCAL(m_blockchain_lock); return m_transactions.size(); } //------------------------------------------------------------------ -bool blockchain_storage::get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys) +bool blockchain_storage::get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); auto it = m_outputs.find(amount); @@ -1392,7 +1382,7 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const return true; } //------------------------------------------------------------------ -bool blockchain_storage::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) +bool blockchain_storage::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); auto it = m_transactions.find(tx_id); @@ -1407,7 +1397,7 @@ bool blockchain_storage::get_tx_outputs_gindexs(const crypto::hash& tx_id, std:: return true; } //------------------------------------------------------------------ -bool blockchain_storage::check_tx_inputs(const transaction& tx, uint64_t& max_used_block_height, crypto::hash& max_used_block_id) +bool blockchain_storage::check_tx_inputs(const transaction& tx, uint64_t& max_used_block_height, crypto::hash& max_used_block_id) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); bool res = check_tx_inputs(tx, &max_used_block_height); @@ -1417,7 +1407,7 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, uint64_t& max_us return true; } //------------------------------------------------------------------ -bool blockchain_storage::have_tx_keyimges_as_spent(const transaction &tx) +bool blockchain_storage::have_tx_keyimges_as_spent(const transaction &tx) const { BOOST_FOREACH(const txin_v& in, tx.vin) { @@ -1428,13 +1418,13 @@ bool blockchain_storage::have_tx_keyimges_as_spent(const transaction &tx) return false; } //------------------------------------------------------------------ -bool blockchain_storage::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height) +bool blockchain_storage::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height) const { crypto::hash tx_prefix_hash = get_transaction_prefix_hash(tx); return check_tx_inputs(tx, tx_prefix_hash, pmax_used_block_height); } //------------------------------------------------------------------ -bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t* pmax_used_block_height) +bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t* pmax_used_block_height) const { size_t sig_index = 0; if(pmax_used_block_height) @@ -1466,7 +1456,7 @@ bool blockchain_storage::check_tx_inputs(const transaction& tx, const crypto::ha return true; } //------------------------------------------------------------------ -bool blockchain_storage::is_tx_spendtime_unlocked(uint64_t unlock_time) +bool blockchain_storage::is_tx_spendtime_unlocked(uint64_t unlock_time) const { if(unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) { @@ -1487,15 +1477,15 @@ bool blockchain_storage::is_tx_spendtime_unlocked(uint64_t unlock_time) return false; } //------------------------------------------------------------------ -bool blockchain_storage::check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height) +bool blockchain_storage::check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); struct outputs_visitor { std::vector<const crypto::public_key *>& m_results_collector; - blockchain_storage& m_bch; - outputs_visitor(std::vector<const crypto::public_key *>& results_collector, blockchain_storage& bch):m_results_collector(results_collector), m_bch(bch) + const blockchain_storage& m_bch; + outputs_visitor(std::vector<const crypto::public_key *>& results_collector, const blockchain_storage& bch):m_results_collector(results_collector), m_bch(bch) {} bool handle_output(const transaction& tx, const tx_out& out) { @@ -1537,13 +1527,13 @@ bool blockchain_storage::check_tx_input(const txin_to_key& txin, const crypto::h return crypto::check_ring_signature(tx_prefix_hash, txin.k_image, output_keys, sig.data()); } //------------------------------------------------------------------ -uint64_t blockchain_storage::get_adjusted_time() +uint64_t blockchain_storage::get_adjusted_time() const { //TODO: add collecting median time return time(NULL); } //------------------------------------------------------------------ -bool blockchain_storage::check_block_timestamp_main(const block& b) +bool blockchain_storage::check_block_timestamp_main(const block& b) const { if(b.timestamp > get_adjusted_time() + CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT) { @@ -1559,7 +1549,7 @@ bool blockchain_storage::check_block_timestamp_main(const block& b) return check_block_timestamp(std::move(timestamps), b); } //------------------------------------------------------------------ -bool blockchain_storage::check_block_timestamp(std::vector<uint64_t> timestamps, const block& b) +bool blockchain_storage::check_block_timestamp(std::vector<uint64_t> timestamps, const block& b) const { if(timestamps.size() < BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW) return true; @@ -1782,7 +1772,7 @@ bool blockchain_storage::add_new_block(const block& bl_, block_verification_cont return handle_block_to_main_chain(bl, id, bvc); } //------------------------------------------------------------------ -void blockchain_storage::check_against_checkpoints(checkpoints& points, bool enforce) +void blockchain_storage::check_against_checkpoints(const checkpoints& points, bool enforce) { const auto& pts = points.get_points(); diff --git a/src/cryptonote_core/blockchain_storage.h b/src/cryptonote_core/blockchain_storage.h index 671da40a8..e26d55b64 100644 --- a/src/cryptonote_core/blockchain_storage.h +++ b/src/cryptonote_core/blockchain_storage.h @@ -88,55 +88,55 @@ namespace cryptonote void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; } //bool push_new_block(); - bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs); - bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks); - bool get_alternative_blocks(std::list<block>& blocks); - size_t get_alternative_blocks_count(); - crypto::hash get_block_id_by_height(uint64_t height); - bool get_block_by_hash(const crypto::hash &h, block &blk); - void get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid); + 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<block>& blocks) const; + bool get_alternative_blocks(std::list<block>& blocks) const; + size_t get_alternative_blocks_count() const; + crypto::hash get_block_id_by_height(uint64_t height) const; + bool get_block_by_hash(const crypto::hash &h, block &blk) const; + void get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid) const; template<class archive_t> void serialize(archive_t & ar, const unsigned int version); - bool have_tx(const crypto::hash &id); - bool have_tx_keyimges_as_spent(const transaction &tx); - bool have_tx_keyimg_as_spent(const crypto::key_image &key_im); - transaction *get_tx(const crypto::hash &id); + bool have_tx(const crypto::hash &id) const; + bool have_tx_keyimges_as_spent(const transaction &tx) const; + bool have_tx_keyimg_as_spent(const crypto::key_image &key_im) const; + const transaction *get_tx(const crypto::hash &id) const; template<class visitor_t> - bool scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height = NULL); + bool scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height = NULL) const; - uint64_t get_current_blockchain_height(); - crypto::hash get_tail_id(); - crypto::hash get_tail_id(uint64_t& height); - difficulty_type get_difficulty_for_next_block(); + uint64_t get_current_blockchain_height() const; + crypto::hash get_tail_id() const; + crypto::hash get_tail_id(uint64_t& height) const; + difficulty_type get_difficulty_for_next_block() const; bool add_new_block(const block& bl_, block_verification_context& bvc); bool reset_and_set_genesis_block(const block& b); - bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, const blobdata& ex_nonce); - bool have_block(const crypto::hash& id); - size_t get_total_transactions(); - bool get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys); - bool get_short_chain_history(std::list<crypto::hash>& ids); - bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp); - bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset); - 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); + bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, const blobdata& ex_nonce) const; + bool have_block(const crypto::hash& id) const; + size_t get_total_transactions() const; + bool get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys) const; + bool get_short_chain_history(std::list<crypto::hash>& ids) const; + bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const; + bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset) 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 handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp); bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res); - bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res); - bool get_backward_blocks_sizes(size_t from_height, std::vector<size_t>& sz, size_t count); - bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs); + bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) const; + bool get_backward_blocks_sizes(size_t from_height, std::vector<size_t>& sz, size_t count) const; + bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const; bool store_blockchain(); - bool check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height = NULL); - bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t* pmax_used_block_height = NULL); - bool check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height = NULL); - bool check_tx_inputs(const transaction& tx, uint64_t& pmax_used_block_height, crypto::hash& max_used_block_id); - uint64_t get_current_comulative_blocksize_limit(); - bool is_storing_blockchain(){return m_is_blockchain_storing;} - uint64_t block_difficulty(size_t i); + bool check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height = NULL) const; + bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t* pmax_used_block_height = NULL) const; + bool check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height = NULL) const; + bool check_tx_inputs(const transaction& tx, uint64_t& pmax_used_block_height, crypto::hash& max_used_block_id) const; + uint64_t get_current_comulative_blocksize_limit() const; + bool is_storing_blockchain()const{return m_is_blockchain_storing;} + uint64_t block_difficulty(size_t i) const; template<class t_ids_container, class t_blocks_container, class t_missed_container> - bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) + bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -156,7 +156,7 @@ namespace cryptonote } 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) + bool get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -180,14 +180,14 @@ namespace cryptonote void print_blockchain(uint64_t start_index, uint64_t end_index); void print_blockchain_index(); void print_blockchain_outs(const std::string& file); - void check_against_checkpoints(checkpoints& points, bool enforce); + void check_against_checkpoints(const checkpoints& points, bool enforce); bool update_checkpoints(const std::string& file_path, bool check_dns); void set_enforce_dns_checkpoints(bool enforce_checkpoints); - block get_block(uint64_t height) { return m_blocks[height].bl; } - size_t get_block_size(uint64_t height) { return m_blocks[height].block_cumulative_size; } - difficulty_type get_block_cumulative_difficulty(uint64_t height) { return m_blocks[height].cumulative_difficulty; } - uint64_t get_block_coins_generated(uint64_t height) { return m_blocks[height].already_generated_coins; } + block get_block(uint64_t height) const { return m_blocks[height].bl; } + size_t get_block_size(uint64_t height) const { return m_blocks[height].block_cumulative_size; } + difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return m_blocks[height].cumulative_difficulty; } + uint64_t get_block_coins_generated(uint64_t height) const { return m_blocks[height].already_generated_coins; } private: typedef std::unordered_map<crypto::hash, size_t> blocks_by_id_index; @@ -199,7 +199,7 @@ namespace cryptonote typedef std::map<uint64_t, std::vector<std::pair<crypto::hash, size_t>>> outputs_container; //crypto::hash - tx hash, size_t - index of out in transaction tx_memory_pool* m_tx_pool; - epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock + mutable epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock // main chain blocks_container m_blocks; // height -> block_extended_info @@ -233,26 +233,26 @@ namespace cryptonote bool handle_block_to_main_chain(const block& bl, block_verification_context& bvc); bool handle_block_to_main_chain(const block& bl, const crypto::hash& id, block_verification_context& bvc); bool handle_alternative_block(const block& b, const crypto::hash& id, block_verification_context& bvc); - difficulty_type get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei); - bool prevalidate_miner_transaction(const block& b, uint64_t height); - bool validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins); - bool validate_transaction(const block& b, uint64_t height, const transaction& tx); + difficulty_type get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei) const; + bool prevalidate_miner_transaction(const block& b, uint64_t height) const; + bool validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins) const; + bool validate_transaction(const block& b, uint64_t height, const transaction& tx) const; bool rollback_blockchain_switching(std::list<block>& original_chain, size_t rollback_height); bool add_transaction_from_block(const transaction& tx, const crypto::hash& tx_id, const crypto::hash& bl_id, uint64_t bl_height); bool push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector<uint64_t>& global_indexes); bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id); - bool get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count); - bool add_out_to_get_random_outs(std::vector<std::pair<crypto::hash, size_t> >& amount_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i); - bool is_tx_spendtime_unlocked(uint64_t unlock_time); + bool get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) const; + bool add_out_to_get_random_outs(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) const; + bool is_tx_spendtime_unlocked(uint64_t unlock_time) const; bool add_block_as_invalid(const block& bl, const crypto::hash& h); bool add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h); - size_t find_end_of_allowed_index(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs); - bool check_block_timestamp_main(const block& b); - bool check_block_timestamp(std::vector<uint64_t> timestamps, const block& b); - uint64_t get_adjusted_time(); - bool complete_timestamps_vector(uint64_t start_height, std::vector<uint64_t>& timestamps); + size_t find_end_of_allowed_index(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs) const; + bool check_block_timestamp_main(const block& b) const; + bool check_block_timestamp(std::vector<uint64_t> timestamps, const block& b) const; + uint64_t get_adjusted_time() const; + bool complete_timestamps_vector(uint64_t start_height, std::vector<uint64_t>& timestamps) const; bool update_next_comulative_size_limit(); - bool store_genesis_block(bool testnet); + bool store_genesis_block(bool testnet, bool check_added = false); }; @@ -320,7 +320,7 @@ namespace cryptonote //------------------------------------------------------------------ template<class visitor_t> - bool blockchain_storage::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height) + bool blockchain_storage::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height) const { CRITICAL_REGION_LOCAL(m_blockchain_lock); auto it = m_outputs.find(tx_in_to_key.amount); @@ -330,7 +330,7 @@ namespace cryptonote std::vector<uint64_t> absolute_offsets = relative_output_offsets_to_absolute(tx_in_to_key.key_offsets); - std::vector<std::pair<crypto::hash, size_t> >& amount_outs_vec = it->second; + const std::vector<std::pair<crypto::hash, size_t> >& amount_outs_vec = it->second; size_t count = 0; BOOST_FOREACH(uint64_t i, absolute_offsets) { @@ -339,7 +339,7 @@ namespace cryptonote LOG_PRINT_L0("Wrong index in transaction inputs: " << i << ", expected maximum " << amount_outs_vec.size() - 1); return false; } - transactions_container::iterator tx_it = m_transactions.find(amount_outs_vec[i].first); + transactions_container::const_iterator tx_it = m_transactions.find(amount_outs_vec[i].first); CHECK_AND_ASSERT_MES(tx_it != m_transactions.end(), false, "Wrong transaction id in output indexes: " << epee::string_tools::pod_to_hex(amount_outs_vec[i].first)); CHECK_AND_ASSERT_MES(amount_outs_vec[i].second < tx_it->second.tx.vout.size(), false, "Wrong index in transaction outputs: " << amount_outs_vec[i].second << ", expected less then " << tx_it->second.tx.vout.size()); diff --git a/src/cryptonote_core/checkpoints.cpp b/src/cryptonote_core/checkpoints.cpp index 73668ab36..58edda7c9 100644 --- a/src/cryptonote_core/checkpoints.cpp +++ b/src/cryptonote_core/checkpoints.cpp @@ -99,7 +99,7 @@ namespace cryptonote return checkpoint_height < block_height; } //--------------------------------------------------------------------------- - uint64_t checkpoints::get_max_height() + uint64_t checkpoints::get_max_height() const { std::map< uint64_t, crypto::hash >::const_iterator highest = std::max_element( m_points.begin(), m_points.end(), @@ -108,18 +108,18 @@ namespace cryptonote return highest->first; } //--------------------------------------------------------------------------- - const std::map<uint64_t, crypto::hash>& checkpoints::get_points() + const std::map<uint64_t, crypto::hash>& checkpoints::get_points() const { return m_points; } - bool checkpoints::check_for_conflicts(checkpoints& other) + bool checkpoints::check_for_conflicts(const checkpoints& other) const { for (auto& pt : other.get_points()) { if (m_points.count(pt.first)) { - CHECK_AND_ASSERT_MES(pt.second == m_points[pt.first], false, "Checkpoint at given height already exists, and hash for new checkpoint was different!"); + CHECK_AND_ASSERT_MES(pt.second == m_points.at(pt.first), false, "Checkpoint at given height already exists, and hash for new checkpoint was different!"); } } return true; diff --git a/src/cryptonote_core/checkpoints.h b/src/cryptonote_core/checkpoints.h index a39ce1964..55d765b71 100644 --- a/src/cryptonote_core/checkpoints.h +++ b/src/cryptonote_core/checkpoints.h @@ -45,9 +45,9 @@ namespace cryptonote bool check_block(uint64_t height, const crypto::hash& h) const; bool check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const; bool is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const; - uint64_t get_max_height(); - const std::map<uint64_t, crypto::hash>& get_points(); - bool check_for_conflicts(checkpoints& other); + uint64_t get_max_height() const; + const std::map<uint64_t, crypto::hash>& get_points() const; + bool check_for_conflicts(const checkpoints& other) const; private: std::map<uint64_t, crypto::hash> m_points; }; |