diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp deleted file mode 100644 index ba39b9b..0000000 --- a/src/cryptonote_core/account.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include - -#include "include_base_utils.h" -#include "account.h" -#include "warnings.h" -#include "crypto/crypto.h" -#include "cryptonote_core/cryptonote_basic_impl.h" -#include "cryptonote_core/cryptonote_format_utils.h" -using namespace std; - -DISABLE_VS_WARNINGS(4244 4345) - - namespace cryptonote -{ - //----------------------------------------------------------------- - account_base::account_base() - { - set_null(); - } - //----------------------------------------------------------------- - void account_base::set_null() - { - m_keys = account_keys(); - } - //----------------------------------------------------------------- - void account_base::generate() - { - generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key); - generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key); - m_creation_timestamp = time(NULL); - } - //----------------------------------------------------------------- - const account_keys& account_base::get_keys() const - { - return m_keys; - } - //----------------------------------------------------------------- - std::string account_base::get_public_address_str() - { - //TODO: change this code into base 58 - return get_account_address_as_str(m_keys.m_account_address); - } - //----------------------------------------------------------------- -} diff --git a/src/cryptonote_core/account_boost_serialization.h b/src/cryptonote_core/account_boost_serialization.h deleted file mode 100644 index 9cc36d1..0000000 --- a/src/cryptonote_core/account_boost_serialization.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -#include "account.h" -#include "cryptonote_core/cryptonote_boost_serialization.h" - -//namespace cryptonote { -namespace boost -{ - namespace serialization - { - template - inline void serialize(Archive &a, cryptonote::account_keys &x, const boost::serialization::version_type ver) - { - a & x.m_account_address; - a & x.m_spend_secret_key; - a & x.m_view_secret_key; - } - - template - inline void serialize(Archive &a, cryptonote::account_public_address &x, const boost::serialization::version_type ver) - { - a & x.m_spend_public_key; - a & x.m_view_public_key; - } - - } -} diff --git a/src/cryptonote_core/blockchain_storage.cpp b/src/cryptonote_core/blockchain_storage.cpp deleted file mode 100644 index 0e20b45..0000000 --- a/src/cryptonote_core/blockchain_storage.cpp +++ /dev/null @@ -1,1651 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include -#include - -#include "include_base_utils.h" -#include "cryptonote_basic_impl.h" -#include "blockchain_storage.h" -#include "cryptonote_format_utils.h" -#include "cryptonote_boost_serialization.h" -#include "blockchain_storage_boost_serialization.h" -#include "cryptonote_config.h" -#include "miner.h" -#include "misc_language.h" -#include "profile_tools.h" -#include "file_io_utils.h" -#include "common/boost_serialization_helper.h" -#include "warnings.h" -#include "crypto/hash.h" -//#include "serialization/json_archive.h" - -using namespace std; -using namespace epee; -using namespace cryptonote; - -DISABLE_VS_WARNINGS(4267) - -//------------------------------------------------------------------ -bool blockchain_storage::have_tx(const crypto::hash &id) -{ - 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) -{ - 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) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - auto it = m_transactions.find(id); - if (it == m_transactions.end()) - return NULL; - - return &it->second.tx; -} -//------------------------------------------------------------------ -uint64_t blockchain_storage::get_current_blockchain_height() -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - return m_blocks.size(); -} -//------------------------------------------------------------------ -bool blockchain_storage::init(const std::string& config_folder) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - m_config_folder = config_folder; - LOG_PRINT_L0("Loading blockchain..."); - const std::string filename = m_config_folder + "/" CRYPTONOTE_BLOCKCHAINDATA_FILENAME; - if(!tools::unserialize_obj_from_file(*this, filename)) - { - LOG_PRINT_L0("Can't load blockchain storage from file, generating genesis block."); - block bl = boost::value_initialized(); - block_verification_context bvc = boost::value_initialized(); - generate_genesis_block(bl); - 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(!m_blocks.size()) - { - LOG_PRINT_L0("Blockchain not loaded, generating genesis block."); - block bl = boost::value_initialized(); - block_verification_context bvc = boost::value_initialized(); - generate_genesis_block(bl); - add_new_block(bl, bvc); - CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false, "Failed to add genesis block to blockchain"); - } - uint64_t timestamp_diff = time(NULL) - m_blocks.back().bl.timestamp; - if(!m_blocks.back().bl.timestamp) - timestamp_diff = time(NULL) - 1341378000; - LOG_PRINT_GREEN("Blockchain initialized. last block: " << m_blocks.size()-1 << ", " << misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block(), LOG_LEVEL_0); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::store_blockchain() -{ - m_is_blockchain_storing = true; - misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){m_is_blockchain_storing=false;}); - - LOG_PRINT_L0("Storing blockchain..."); - if (!tools::create_directories_if_necessary(m_config_folder)) - { - LOG_PRINT_L0("Failed to create data directory: " << m_config_folder); - return false; - } - - const std::string temp_filename = m_config_folder + "/" CRYPTONOTE_BLOCKCHAINDATA_TEMP_FILENAME; - // There is a chance that temp_filename and filename are hardlinks to the same file - std::remove(temp_filename.c_str()); - if(!tools::serialize_obj_to_file(*this, temp_filename)) - { - //achtung! - LOG_ERROR("Failed to save blockchain data to file: " << temp_filename); - return false; - } - const std::string filename = m_config_folder + "/" CRYPTONOTE_BLOCKCHAINDATA_FILENAME; - std::error_code ec = tools::replace_file(temp_filename, filename); - if (ec) - { - LOG_ERROR("Failed to rename blockchain data file " << temp_filename << " to " << filename << ": " << ec.message() << ':' << ec.value()); - return false; - } - LOG_PRINT_L0("Blockchain stored OK."); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::deinit() -{ - return store_blockchain(); -} -//------------------------------------------------------------------ -bool blockchain_storage::pop_block_from_blockchain() -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - CHECK_AND_ASSERT_MES(m_blocks.size() > 1, false, "pop_block_from_blockchain: can't pop from blockchain with size = " << m_blocks.size()); - size_t h = m_blocks.size()-1; - block_extended_info& bei = m_blocks[h]; - //crypto::hash id = get_block_hash(bei.bl); - bool r = purge_block_data_from_blockchain(bei.bl, bei.bl.tx_hashes.size()); - CHECK_AND_ASSERT_MES(r, false, "Failed to purge_block_data_from_blockchain for block " << get_block_hash(bei.bl) << " on height " << h); - - //remove from index - auto bl_ind = m_blocks_index.find(get_block_hash(bei.bl)); - CHECK_AND_ASSERT_MES(bl_ind != m_blocks_index.end(), false, "pop_block_from_blockchain: blockchain id not found in index"); - m_blocks_index.erase(bl_ind); - //pop block from core - m_blocks.pop_back(); - m_tx_pool.on_blockchain_dec(m_blocks.size()-1, get_tail_id()); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::reset_and_set_genesis_block(const block& b) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - m_transactions.clear(); - m_spent_keys.clear(); - m_blocks.clear(); - m_blocks_index.clear(); - m_alternative_chains.clear(); - m_outputs.clear(); - - block_verification_context bvc = boost::value_initialized(); - add_new_block(b, bvc); - return bvc.m_added_to_main_chain && !bvc.m_verifivation_failed; -} -//------------------------------------------------------------------ -bool blockchain_storage::purge_transaction_keyimages_from_blockchain(const transaction& tx, bool strict_check) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - struct purge_transaction_visitor: public boost::static_visitor - { - key_images_container& m_spent_keys; - bool m_strict_check; - purge_transaction_visitor(key_images_container& spent_keys, bool strict_check):m_spent_keys(spent_keys), m_strict_check(strict_check){} - - bool operator()(const txin_to_key& inp) const - { - //const crypto::key_image& ki = inp.k_image; - auto r = m_spent_keys.find(inp.k_image); - if(r != m_spent_keys.end()) - { - m_spent_keys.erase(r); - }else - { - CHECK_AND_ASSERT_MES(!m_strict_check, false, "purge_block_data_from_blockchain: key image in transaction not found"); - } - return true; - } - bool operator()(const txin_gen& inp) const - { - return true; - } - bool operator()(const txin_to_script& tx) const - { - return false; - } - - bool operator()(const txin_to_scripthash& tx) const - { - return false; - } - }; - - BOOST_FOREACH(const txin_v& in, tx.vin) - { - bool r = boost::apply_visitor(purge_transaction_visitor(m_spent_keys, strict_check), in); - CHECK_AND_ASSERT_MES(!strict_check || r, false, "failed to process purge_transaction_visitor"); - } - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::purge_transaction_from_blockchain(const crypto::hash& tx_id) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - auto tx_index_it = m_transactions.find(tx_id); - CHECK_AND_ASSERT_MES(tx_index_it != m_transactions.end(), false, "purge_block_data_from_blockchain: transaction not found in blockchain index!!"); - transaction& tx = tx_index_it->second.tx; - - purge_transaction_keyimages_from_blockchain(tx, true); - - if(!is_coinbase(tx)) - { - cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc); - bool r = m_tx_pool.add_tx(tx, tvc, true); - CHECK_AND_ASSERT_MES(r, false, "purge_block_data_from_blockchain: failed to add transaction to transaction pool"); - } - - bool res = pop_transaction_from_global_index(tx, tx_id); - m_transactions.erase(tx_index_it); - LOG_PRINT_L1("Removed transaction from blockchain history:" << tx_id << ENDL); - return res; -} -//------------------------------------------------------------------ -bool blockchain_storage::purge_block_data_from_blockchain(const block& bl, size_t processed_tx_count) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - bool res = true; - CHECK_AND_ASSERT_MES(processed_tx_count <= bl.tx_hashes.size(), false, "wrong processed_tx_count in purge_block_data_from_blockchain"); - for(size_t count = 0; count != processed_tx_count; count++) - { - res = purge_transaction_from_blockchain(bl.tx_hashes[(processed_tx_count -1)- count]) && res; - } - - res = purge_transaction_from_blockchain(get_transaction_hash(bl.miner_tx)) && res; - - return res; -} -//------------------------------------------------------------------ -crypto::hash blockchain_storage::get_tail_id(uint64_t& height) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - height = get_current_blockchain_height()-1; - return get_tail_id(); -} -//------------------------------------------------------------------ -crypto::hash blockchain_storage::get_tail_id() -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - crypto::hash id = null_hash; - if(m_blocks.size()) - { - get_block_hash(m_blocks.back().bl, id); - } - return id; -} -//------------------------------------------------------------------ -bool blockchain_storage::get_short_chain_history(std::list& ids) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - size_t i = 0; - size_t current_multiplier = 1; - size_t sz = m_blocks.size(); - if(!sz) - return true; - size_t current_back_offset = 1; - bool genesis_included = false; - while(current_back_offset < sz) - { - ids.push_back(get_block_hash(m_blocks[sz-current_back_offset].bl)); - if(sz-current_back_offset == 0) - genesis_included = true; - if(i < 10) - { - ++current_back_offset; - }else - { - current_back_offset += current_multiplier *= 2; - } - ++i; - } - if(!genesis_included) - ids.push_back(get_block_hash(m_blocks[0].bl)); - - return true; -} -//------------------------------------------------------------------ -crypto::hash blockchain_storage::get_block_id_by_height(uint64_t height) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(height >= m_blocks.size()) - return null_hash; - - return get_block_hash(m_blocks[height].bl); -} -//------------------------------------------------------------------ -bool blockchain_storage::get_block_by_hash(const crypto::hash &h, block &blk) { - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - // try to find block in main chain - blocks_by_id_index::const_iterator it = m_blocks_index.find(h); - if (m_blocks_index.end() != it) { - blk = m_blocks[it->second].bl; - return true; - } - - // try to find block in alternative chain - blocks_ext_by_hash::const_iterator it_alt = m_alternative_chains.find(h); - if (m_alternative_chains.end() != it_alt) { - blk = it_alt->second.bl; - return true; - } - - return false; -} -//------------------------------------------------------------------ -void blockchain_storage::get_all_known_block_ids(std::list &main, std::list &alt, std::list &invalid) { - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - BOOST_FOREACH(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) - alt.push_back(v.first); - - BOOST_FOREACH(blocks_ext_by_hash::value_type &v, m_invalid_blocks) - invalid.push_back(v.first); -} -//------------------------------------------------------------------ -difficulty_type blockchain_storage::get_difficulty_for_next_block() -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - std::vector timestamps; - std::vector commulative_difficulties; - size_t offset = m_blocks.size() - std::min(m_blocks.size(), static_cast(DIFFICULTY_BLOCKS_COUNT)); - if(!offset) - ++offset;//skip genesis block - for(; offset < m_blocks.size(); offset++) - { - timestamps.push_back(m_blocks[offset].bl.timestamp); - commulative_difficulties.push_back(m_blocks[offset].cumulative_difficulty); - } - return next_difficulty(timestamps, commulative_difficulties); -} -//------------------------------------------------------------------ -bool blockchain_storage::rollback_blockchain_switching(std::list& original_chain, size_t rollback_height) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - //remove failed subchain - for(size_t i = m_blocks.size()-1; i >=rollback_height; i--) - { - bool r = pop_block_from_blockchain(); - CHECK_AND_ASSERT_MES(r, false, "PANIC!!! failed to remove block while chain switching during the rollback!"); - } - //return back original chain - BOOST_FOREACH(auto& bl, original_chain) - { - block_verification_context bvc = boost::value_initialized(); - bool r = handle_block_to_main_chain(bl, bvc); - CHECK_AND_ASSERT_MES(r && bvc.m_added_to_main_chain, false, "PANIC!!! failed to add (again) block while chain switching during the rollback!"); - } - - LOG_PRINT_L0("Rollback success."); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::switch_to_alternative_blockchain(std::list& alt_chain) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - CHECK_AND_ASSERT_MES(alt_chain.size(), false, "switch_to_alternative_blockchain: empty chain passed"); - - size_t split_height = alt_chain.front()->second.height; - CHECK_AND_ASSERT_MES(m_blocks.size() > split_height, false, "switch_to_alternative_blockchain: blockchain size is lower than split height"); - - //disconnecting old chain - std::list disconnected_chain; - for(size_t i = m_blocks.size()-1; i >=split_height; i--) - { - block b = m_blocks[i].bl; - bool r = pop_block_from_blockchain(); - CHECK_AND_ASSERT_MES(r, false, "failed to remove block on chain switching"); - disconnected_chain.push_front(b); - } - - //connecting new alternative chain - for(auto alt_ch_iter = alt_chain.begin(); alt_ch_iter != alt_chain.end(); alt_ch_iter++) - { - auto ch_ent = *alt_ch_iter; - block_verification_context bvc = boost::value_initialized(); - bool r = handle_block_to_main_chain(ch_ent->second.bl, bvc); - if(!r || !bvc.m_added_to_main_chain) - { - LOG_PRINT_L0("Failed to switch to alternative blockchain"); - rollback_blockchain_switching(disconnected_chain, split_height); - add_block_as_invalid(ch_ent->second, get_block_hash(ch_ent->second.bl)); - LOG_PRINT_L0("The block was inserted as invalid while connecting new alternative chain, block_id: " << get_block_hash(ch_ent->second.bl)); - m_alternative_chains.erase(ch_ent); - - for(auto alt_ch_to_orph_iter = ++alt_ch_iter; alt_ch_to_orph_iter != alt_chain.end(); alt_ch_to_orph_iter++) - { - //block_verification_context bvc = boost::value_initialized(); - add_block_as_invalid((*alt_ch_iter)->second, (*alt_ch_iter)->first); - m_alternative_chains.erase(*alt_ch_to_orph_iter); - } - return false; - } - } - - //pushing old chain as alternative chain - BOOST_FOREACH(auto& old_ch_ent, disconnected_chain) - { - block_verification_context bvc = boost::value_initialized(); - bool r = handle_alternative_block(old_ch_ent, get_block_hash(old_ch_ent), bvc); - if(!r) - { - LOG_ERROR("Failed to push ex-main chain blocks to alternative chain "); - rollback_blockchain_switching(disconnected_chain, split_height); - return false; - } - } - - //removing all_chain entries from alternative chain - BOOST_FOREACH(auto ch_ent, alt_chain) - { - m_alternative_chains.erase(ch_ent); - } - - LOG_PRINT_GREEN("REORGANIZE SUCCESS! on height: " << split_height << ", new blockchain size: " << m_blocks.size(), LOG_LEVEL_0); - return true; -} -//------------------------------------------------------------------ -difficulty_type blockchain_storage::get_next_difficulty_for_alternative_chain(const std::list& alt_chain, block_extended_info& bei) -{ - std::vector timestamps; - std::vector commulative_difficulties; - if(alt_chain.size()< DIFFICULTY_BLOCKS_COUNT) - { - CRITICAL_REGION_LOCAL(m_blockchain_lock); - size_t main_chain_stop_offset = alt_chain.size() ? alt_chain.front()->second.height : bei.height; - size_t main_chain_count = DIFFICULTY_BLOCKS_COUNT - std::min(static_cast(DIFFICULTY_BLOCKS_COUNT), alt_chain.size()); - main_chain_count = std::min(main_chain_count, main_chain_stop_offset); - size_t main_chain_start_offset = main_chain_stop_offset - main_chain_count; - - if(!main_chain_start_offset) - ++main_chain_start_offset; //skip genesis block - for(; main_chain_start_offset < main_chain_stop_offset; ++main_chain_start_offset) - { - timestamps.push_back(m_blocks[main_chain_start_offset].bl.timestamp); - commulative_difficulties.push_back(m_blocks[main_chain_start_offset].cumulative_difficulty); - } - - CHECK_AND_ASSERT_MES((alt_chain.size() + timestamps.size()) <= DIFFICULTY_BLOCKS_COUNT, false, "Internal error, alt_chain.size()["<< alt_chain.size() - << "] + vtimestampsec.size()[" << timestamps.size() << "] NOT <= DIFFICULTY_WINDOW[]" << DIFFICULTY_BLOCKS_COUNT ); - BOOST_FOREACH(auto it, alt_chain) - { - timestamps.push_back(it->second.bl.timestamp); - commulative_difficulties.push_back(it->second.cumulative_difficulty); - } - }else - { - timestamps.resize(std::min(alt_chain.size(), static_cast(DIFFICULTY_BLOCKS_COUNT))); - commulative_difficulties.resize(std::min(alt_chain.size(), static_cast(DIFFICULTY_BLOCKS_COUNT))); - size_t count = 0; - size_t max_i = timestamps.size()-1; - BOOST_REVERSE_FOREACH(auto it, alt_chain) - { - timestamps[max_i - count] = it->second.bl.timestamp; - commulative_difficulties[max_i - count] = it->second.cumulative_difficulty; - count++; - if(count >= DIFFICULTY_BLOCKS_COUNT) - break; - } - } - return next_difficulty(timestamps, commulative_difficulties); -} -//------------------------------------------------------------------ -bool blockchain_storage::prevalidate_miner_transaction(const block& b, uint64_t height) -{ - 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"); - if(boost::get(b.miner_tx.vin[0]).height != height) - { - LOG_PRINT_RED_L0("The miner transaction in block has invalid height: " << boost::get(b.miner_tx.vin[0]).height << ", expected: " << height); - return false; - } - CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, - false, - "coinbase transaction transaction have wrong unlock time=" << b.miner_tx.unlock_time << ", expected " << height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW); - - //check outs overflow - if(!check_outs_overflow(b.miner_tx)) - { - LOG_PRINT_RED_L0("miner transaction have money overflow in block " << get_block_hash(b)); - return false; - } - - 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) -{ - //validate reward - uint64_t money_in_use = 0; - BOOST_FOREACH(auto& o, b.miner_tx.vout) - money_in_use += o.amount; - - std::vector last_blocks_sizes; - get_last_n_blocks_sizes(last_blocks_sizes, CRYPTONOTE_REWARD_BLOCKS_WINDOW); - if(!get_block_reward(misc_utils::median(last_blocks_sizes), cumulative_block_size, already_generated_coins, base_reward)) - { - LOG_PRINT_L0("block size " << cumulative_block_size << " is bigger than allowed for this blockchain"); - return false; - } - if(base_reward + fee < money_in_use) - { - LOG_ERROR("coinbase transaction spend too much money (" << print_money(money_in_use) << "). Block reward is " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << ")"); - return false; - } - if(base_reward + fee != money_in_use) - { - LOG_ERROR("coinbase transaction doesn't use full amount of block reward: spent: " - << print_money(money_in_use) << ", block reward " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << ")"); - return false; - } - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::get_backward_blocks_sizes(size_t from_height, std::vector& sz, size_t count) -{ - 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()); - - size_t start_offset = (from_height+1) - std::min((from_height+1), count); - for(size_t i = start_offset; i != from_height+1; i++) - sz.push_back(m_blocks[i].block_cumulative_size); - - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::get_last_n_blocks_sizes(std::vector& sz, size_t count) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(!m_blocks.size()) - return true; - return get_backward_blocks_sizes(m_blocks.size() -1, sz, count); -} -//------------------------------------------------------------------ -uint64_t blockchain_storage::get_current_comulative_blocksize_limit() -{ - 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) -{ - size_t median_size; - uint64_t already_generated_coins; - - CRITICAL_REGION_BEGIN(m_blockchain_lock); - b.major_version = CURRENT_BLOCK_MAJOR_VERSION; - b.minor_version = CURRENT_BLOCK_MINOR_VERSION; - b.prev_id = get_tail_id(); - b.timestamp = time(NULL); - height = m_blocks.size(); - diffic = get_difficulty_for_next_block(); - CHECK_AND_ASSERT_MES(diffic, false, "difficulty owverhead."); - - median_size = m_current_block_cumul_sz_limit / 2; - already_generated_coins = m_blocks.back().already_generated_coins; - - CRITICAL_REGION_END(); - - size_t txs_size; - uint64_t fee; - if (!m_tx_pool.fill_block_template(b, median_size, already_generated_coins, txs_size, fee)) { - return false; - } -#if defined(DEBUG_CREATE_BLOCK_TEMPLATE) - size_t real_txs_size = 0; - uint64_t real_fee = 0; - CRITICAL_REGION_BEGIN(m_tx_pool.m_transactions_lock); - BOOST_FOREACH(crypto::hash &cur_hash, b.tx_hashes) { - auto cur_res = m_tx_pool.m_transactions.find(cur_hash); - if (cur_res == m_tx_pool.m_transactions.end()) { - LOG_ERROR("Creating block template: error: transaction not found"); - continue; - } - tx_memory_pool::tx_details &cur_tx = cur_res->second; - real_txs_size += cur_tx.blob_size; - real_fee += cur_tx.fee; - if (cur_tx.blob_size != get_object_blobsize(cur_tx.tx)) { - LOG_ERROR("Creating block template: error: invalid transaction size"); - } - uint64_t inputs_amount; - if (!get_inputs_money_amount(cur_tx.tx, inputs_amount)) { - LOG_ERROR("Creating block template: error: cannot get inputs amount"); - } else if (cur_tx.fee != inputs_amount - get_outs_money_amount(cur_tx.tx)) { - LOG_ERROR("Creating block template: error: invalid fee"); - } - } - if (txs_size != real_txs_size) { - LOG_ERROR("Creating block template: error: wrongly calculated transaction size"); - } - if (fee != real_fee) { - LOG_ERROR("Creating block template: error: wrongly calculated fee"); - } - CRITICAL_REGION_END(); - LOG_PRINT_L1("Creating block template: height " << height << - ", median size " << median_size << - ", already generated coins " << already_generated_coins << - ", transaction size " << txs_size << - ", fee " << fee); -#endif - - /* - two-phase miner transaction generation: we don't know exact block size until we prepare block, but we don't know reward until we know - block size, so first miner transaction generated with fake amount of money, and with phase we know think we know expected block size - */ - //make blocks coin-base tx looks close to real coinbase tx to get truthful blob size - bool r = construct_miner_tx(height, median_size, already_generated_coins, txs_size, fee, miner_address, b.miner_tx, ex_nonce, 11); - CHECK_AND_ASSERT_MES(r, false, "Failed to construc miner tx, first chance"); - size_t cumulative_size = txs_size + get_object_blobsize(b.miner_tx); -#if defined(DEBUG_CREATE_BLOCK_TEMPLATE) - LOG_PRINT_L1("Creating block template: miner tx size " << get_object_blobsize(b.miner_tx) << - ", cumulative size " << cumulative_size); -#endif - for (size_t try_count = 0; try_count != 10; ++try_count) { - r = construct_miner_tx(height, median_size, already_generated_coins, cumulative_size, fee, miner_address, b.miner_tx, ex_nonce, 11); - - CHECK_AND_ASSERT_MES(r, false, "Failed to construc miner tx, second chance"); - size_t coinbase_blob_size = get_object_blobsize(b.miner_tx); - if (coinbase_blob_size > cumulative_size - txs_size) { - cumulative_size = txs_size + coinbase_blob_size; -#if defined(DEBUG_CREATE_BLOCK_TEMPLATE) - LOG_PRINT_L1("Creating block template: miner tx size " << coinbase_blob_size << - ", cumulative size " << cumulative_size << " is greater then before"); -#endif - continue; - } - - if (coinbase_blob_size < cumulative_size - txs_size) { - size_t delta = cumulative_size - txs_size - coinbase_blob_size; -#if defined(DEBUG_CREATE_BLOCK_TEMPLATE) - LOG_PRINT_L1("Creating block template: miner tx size " << coinbase_blob_size << - ", cumulative size " << txs_size + coinbase_blob_size << - " is less then before, adding " << delta << " zero bytes"); -#endif - b.miner_tx.extra.insert(b.miner_tx.extra.end(), delta, 0); - //here could be 1 byte difference, because of extra field counter is varint, and it can become from 1-byte len to 2-bytes len. - if (cumulative_size != txs_size + get_object_blobsize(b.miner_tx)) { - CHECK_AND_ASSERT_MES(cumulative_size + 1 == txs_size + get_object_blobsize(b.miner_tx), false, "unexpected case: cumulative_size=" << cumulative_size << " + 1 is not equal txs_cumulative_size=" << txs_size << " + get_object_blobsize(b.miner_tx)=" << get_object_blobsize(b.miner_tx)); - b.miner_tx.extra.resize(b.miner_tx.extra.size() - 1); - if (cumulative_size != txs_size + get_object_blobsize(b.miner_tx)) { - //fuck, not lucky, -1 makes varint-counter size smaller, in that case we continue to grow with cumulative_size - LOG_PRINT_RED("Miner tx creation have no luck with delta_extra size = " << delta << " and " << delta - 1 , LOG_LEVEL_2); - cumulative_size += delta - 1; - continue; - } - LOG_PRINT_GREEN("Setting extra for block: " << b.miner_tx.extra.size() << ", try_count=" << try_count, LOG_LEVEL_1); - } - } - CHECK_AND_ASSERT_MES(cumulative_size == txs_size + get_object_blobsize(b.miner_tx), false, "unexpected case: cumulative_size=" << cumulative_size << " is not equal txs_cumulative_size=" << txs_size << " + get_object_blobsize(b.miner_tx)=" << get_object_blobsize(b.miner_tx)); -#if defined(DEBUG_CREATE_BLOCK_TEMPLATE) - LOG_PRINT_L1("Creating block template: miner tx size " << coinbase_blob_size << - ", cumulative size " << cumulative_size << " is now good"); -#endif - return true; - } - LOG_ERROR("Failed to create_block_template with " << 10 << " tries"); - return false; -} -//------------------------------------------------------------------ -bool blockchain_storage::complete_timestamps_vector(uint64_t start_top_height, std::vector& timestamps) -{ - - if(timestamps.size() >= BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW) - return true; - - CRITICAL_REGION_LOCAL(m_blockchain_lock); - size_t need_elements = BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW - timestamps.size(); - CHECK_AND_ASSERT_MES(start_top_height < m_blocks.size(), false, "internal error: passed start_height = " << start_top_height << " not less then m_blocks.size()=" << m_blocks.size()); - size_t stop_offset = start_top_height > need_elements ? start_top_height - need_elements:0; - do - { - timestamps.push_back(m_blocks[start_top_height].bl.timestamp); - if(start_top_height == 0) - break; - --start_top_height; - }while(start_top_height != stop_offset); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::handle_alternative_block(const block& b, const crypto::hash& id, block_verification_context& bvc) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - //block is not related with head of main chain - //first of all - look in alternative chains container - auto it_main_prev = m_blocks_index.find(b.prev_id); - auto it_prev = m_alternative_chains.find(b.prev_id); - if(it_prev != m_alternative_chains.end() || it_main_prev != m_blocks_index.end()) - { - //we have new block in alternative chain - - //build alternative subchain, front -> mainchain, back -> alternative head - blocks_ext_by_hash::iterator alt_it = it_prev; //m_alternative_chains.find() - std::list alt_chain; - std::vector timestamps; - while(alt_it != m_alternative_chains.end()) - { - alt_chain.push_front(alt_it); - timestamps.push_back(alt_it->second.bl.timestamp); - alt_it = m_alternative_chains.find(alt_it->second.bl.prev_id); - } - - if(alt_chain.size()) - { - //make sure that it has right connection to main chain - CHECK_AND_ASSERT_MES(m_blocks.size() > alt_chain.front()->second.height, false, "main blockchain wrong height"); - crypto::hash h = null_hash; - get_block_hash(m_blocks[alt_chain.front()->second.height - 1].bl, h); - CHECK_AND_ASSERT_MES(h == alt_chain.front()->second.bl.prev_id, false, "alternative chain have wrong connection to main chain"); - complete_timestamps_vector(alt_chain.front()->second.height - 1, timestamps); - }else - { - CHECK_AND_ASSERT_MES(it_main_prev != m_blocks_index.end(), false, "internal error: broken imperative condition it_main_prev != m_blocks_index.end()"); - complete_timestamps_vector(it_main_prev->second, timestamps); - } - //check timestamp correct - if(!check_block_timestamp(timestamps, b)) - { - LOG_PRINT_RED_L0("Block with id: " << id - << ENDL << " for alternative chain, have invalid timestamp: " << b.timestamp); - //add_block_as_invalid(b, id);//do not add blocks to invalid storage before proof of work check was passed - bvc.m_verifivation_failed = true; - return false; - } - - block_extended_info bei = boost::value_initialized(); - bei.bl = b; - bei.height = alt_chain.size() ? it_prev->second.height + 1 : it_main_prev->second + 1; - difficulty_type current_diff = get_next_difficulty_for_alternative_chain(alt_chain, bei); - CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!"); - crypto::hash proof_of_work = null_hash; - if(!m_checkpoints.is_in_checkpoint_zone(bei.height)) - { - m_is_in_checkpoint_zone = false; - get_block_longhash(bei.bl, proof_of_work, bei.height); - - if(!check_hash(proof_of_work, current_diff)) - { - LOG_PRINT_RED_L0("Block with id: " << id - << ENDL << " for alternative chain, have not enough proof of work: " << proof_of_work - << ENDL << " expected difficulty: " << current_diff); - bvc.m_verifivation_failed = true; - return false; - } - }else - { - m_is_in_checkpoint_zone = true; - if(!m_checkpoints.check_block(bei.height, id)) - { - LOG_ERROR("CHECKPOINT VALIDATION FAILED"); - bvc.m_verifivation_failed = true; - return false; - } - } - - if(!prevalidate_miner_transaction(b, bei.height)) - { - LOG_PRINT_RED_L0("Block with id: " << string_tools::pod_to_hex(id) - << " (as alternative) have wrong miner transaction."); - bvc.m_verifivation_failed = true; - return false; - - } - - bei.cumulative_difficulty = alt_chain.size() ? it_prev->second.cumulative_difficulty: m_blocks[it_main_prev->second].cumulative_difficulty; - bei.cumulative_difficulty += current_diff; - -#ifdef _DEBUG - auto i_dres = m_alternative_chains.find(id); - CHECK_AND_ASSERT_MES(i_dres == m_alternative_chains.end(), false, "insertion of new alternative block returned as it already exist"); -#endif - auto i_res = m_alternative_chains.insert(blocks_ext_by_hash::value_type(id, bei)); - CHECK_AND_ASSERT_MES(i_res.second, false, "insertion of new alternative block returned as it already exist"); - alt_chain.push_back(i_res.first); - //check if difficulty bigger then in main chain - if(m_blocks.back().cumulative_difficulty < bei.cumulative_difficulty) - { - //do reorganize! - LOG_PRINT_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_blocks.size() -1 << " with cum_difficulty " << m_blocks.back().cumulative_difficulty - << ENDL << " alternative blockchain size: " << alt_chain.size() << " with cum_difficulty " << bei.cumulative_difficulty, LOG_LEVEL_0); - bool r = switch_to_alternative_blockchain(alt_chain); - if(r) bvc.m_added_to_main_chain = true; - else bvc.m_verifivation_failed = true; - return r; - } - LOG_PRINT_BLUE("----- BLOCK ADDED AS ALTERNATIVE ON HEIGHT " << bei.height - << ENDL << "id:\t" << id - << ENDL << "PoW:\t" << proof_of_work - << ENDL << "difficulty:\t" << current_diff, LOG_LEVEL_0); - return true; - }else - { - //block orphaned - bvc.m_marked_as_orphaned = true; - LOG_PRINT_RED_L0("Block recognized as orphaned and rejected, id = " << id); - } - - - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::list& blocks, std::list& txs) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(start_offset >= m_blocks.size()) - return false; - for(size_t i = start_offset; i < start_offset + count && i < m_blocks.size();i++) - { - blocks.push_back(m_blocks[i].bl); - std::list missed_ids; - get_transactions(m_blocks[i].bl.tx_hashes, txs, missed_ids); - CHECK_AND_ASSERT_MES(!missed_ids.size(), false, "have missed transactions in own block in main blockchain"); - } - - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::get_blocks(uint64_t start_offset, size_t count, std::list& blocks) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(start_offset >= m_blocks.size()) - return false; - - for(size_t i = start_offset; i < start_offset + count && i < m_blocks.size();i++) - blocks.push_back(m_blocks[i].bl); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - rsp.current_blockchain_height = get_current_blockchain_height(); - std::list blocks; - get_blocks(arg.blocks, blocks, rsp.missed_ids); - - BOOST_FOREACH(const auto& bl, blocks) - { - std::list missed_tx_id; - std::list txs; - get_transactions(bl.tx_hashes, txs, rsp.missed_ids); - CHECK_AND_ASSERT_MES(!missed_tx_id.size(), false, "Internal error: have missed missed_tx_id.size()=" << missed_tx_id.size() - << ENDL << "for block id = " << get_block_hash(bl)); - rsp.blocks.push_back(block_complete_entry()); - block_complete_entry& e = rsp.blocks.back(); - //pack block - e.block = t_serializable_object_to_blob(bl); - //pack transactions - BOOST_FOREACH(transaction& tx, txs) - e.txs.push_back(t_serializable_object_to_blob(tx)); - - } - //get another transactions, if need - std::list txs; - get_transactions(arg.txs, txs, rsp.missed_ids); - //pack aside transactions - BOOST_FOREACH(const auto& tx, txs) - rsp.txs.push_back(t_serializable_object_to_blob(tx)); - - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::get_alternative_blocks(std::list& blocks) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - BOOST_FOREACH(const auto& alt_bl, m_alternative_chains) - { - blocks.push_back(alt_bl.second.bl); - } - return true; -} -//------------------------------------------------------------------ -size_t blockchain_storage::get_alternative_blocks_count() -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - return m_alternative_chains.size(); -} -//------------------------------------------------------------------ -bool blockchain_storage::add_out_to_get_random_outs(std::vector >& amount_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - transactions_container::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; - 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 - if(!is_tx_spendtime_unlocked(tx.unlock_time)) - return false; - - COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry& oen = *result_outs.outs.insert(result_outs.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::out_entry()); - oen.global_amount_index = i; - oen.out_key = boost::get(tx.vout[amount_outs[i].second].target).key; - return true; -} -//------------------------------------------------------------------ -size_t blockchain_storage::find_end_of_allowed_index(const std::vector >& amount_outs) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(!amount_outs.size()) - return 0; - size_t i = amount_outs.size(); - do - { - --i; - transactions_container::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; - } while (i != 0); - 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) -{ - srand(static_cast(time(NULL))); - CRITICAL_REGION_LOCAL(m_blockchain_lock); - BOOST_FOREACH(uint64_t amount, req.amounts) - { - COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs = *res.outs.insert(res.outs.end(), COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount()); - result_outs.amount = amount; - auto it = m_outputs.find(amount); - if(it == m_outputs.end()) - { - LOG_ERROR("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 >& 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); - CHECK_AND_ASSERT_MES(up_index_limit <= amount_outs.size(), false, "internal error: find_end_of_allowed_index returned wrong index=" << up_index_limit << ", with amount_outs.size = " << amount_outs.size()); - if(amount_outs.size() > req.outs_count) - { - std::set used; - size_t try_count = 0; - for(uint64_t j = 0; j != req.outs_count && try_count < up_index_limit;) - { - size_t i = rand()%up_index_limit; - if(used.count(i)) - continue; - bool added = add_out_to_get_random_outs(amount_outs, result_outs, amount, i); - used.insert(i); - if(added) - ++j; - ++try_count; - } - }else - { - for(size_t i = 0; i != up_index_limit; i++) - add_out_to_get_random_outs(amount_outs, result_outs, amount, i); - } - } - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::find_blockchain_supplement(const std::list& qblock_ids, uint64_t& starter_offset) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - if(!qblock_ids.size() /*|| !req.m_total_height*/) - { - LOG_ERROR("Client sent wrong NOTIFY_REQUEST_CHAIN: m_block_ids.size()=" << qblock_ids.size() << /*", m_height=" << req.m_total_height <<*/ ", dropping connection"); - return false; - } - //check genesis match - if(qblock_ids.back() != get_block_hash(m_blocks[0].bl)) - { - LOG_ERROR("Client sent wrong NOTIFY_REQUEST_CHAIN: genesis block missmatch: " << ENDL << "id: " - << qblock_ids.back() << ", " << ENDL << "expected: " << get_block_hash(m_blocks[0].bl) - << "," << ENDL << " dropping connection"); - return false; - } - - /* Figure out what blocks we should request to get state_normal */ - size_t i = 0; - auto bl_it = qblock_ids.begin(); - auto block_index_it = m_blocks_index.find(*bl_it); - for(; bl_it != qblock_ids.end(); bl_it++, i++) - { - block_index_it = m_blocks_index.find(*bl_it); - if(block_index_it != m_blocks_index.end()) - break; - } - - if(bl_it == qblock_ids.end()) - { - LOG_ERROR("Internal error handling connection, can't find split point"); - return false; - } - - if(block_index_it == m_blocks_index.end()) - { - //this should NEVER happen, but, dose of paranoia in such cases is not too bad - LOG_ERROR("Internal error handling connection, can't find split point"); - return false; - } - - //we start to put block ids INCLUDING last known id, just to make other side be sure - starter_offset = block_index_it->second; - return true; -} -//------------------------------------------------------------------ -uint64_t blockchain_storage::block_difficulty(size_t i) -{ - 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()"); - if(i == 0) - return m_blocks[i].cumulative_difficulty; - - return m_blocks[i].cumulative_difficulty - m_blocks[i-1].cumulative_difficulty; -} -//------------------------------------------------------------------ -void blockchain_storage::print_blockchain(uint64_t start_index, uint64_t end_index) -{ - std::stringstream ss; - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(start_index >=m_blocks.size()) - { - LOG_PRINT_L0("Wrong starter index set: " << start_index << ", expected max index " << m_blocks.size()-1); - return; - } - - for(size_t i = start_index; i != m_blocks.size() && i != end_index; i++) - { - ss << "height " << i << ", timestamp " << m_blocks[i].bl.timestamp << ", cumul_dif " << m_blocks[i].cumulative_difficulty << ", cumul_size " << m_blocks[i].block_cumulative_size - << "\nid\t\t" << get_block_hash(m_blocks[i].bl) - << "\ndifficulty\t\t" << block_difficulty(i) << ", nonce " << m_blocks[i].bl.nonce << ", tx_count " << m_blocks[i].bl.tx_hashes.size() << ENDL; - } - LOG_PRINT_L1("Current blockchain:" << ENDL << ss.str()); - LOG_PRINT_L0("Blockchain printed with log level 1"); -} -//------------------------------------------------------------------ -void blockchain_storage::print_blockchain_index() -{ - std::stringstream ss; - CRITICAL_REGION_LOCAL(m_blockchain_lock); - BOOST_FOREACH(const blocks_by_id_index::value_type& v, m_blocks_index) - ss << "id\t\t" << v.first << " height" << v.second << ENDL << ""; - - LOG_PRINT_L0("Current blockchain index:" << ENDL << ss.str()); -} -//------------------------------------------------------------------ -void blockchain_storage::print_blockchain_outs(const std::string& file) -{ - std::stringstream ss; - CRITICAL_REGION_LOCAL(m_blockchain_lock); - BOOST_FOREACH(const outputs_container::value_type& v, m_outputs) - { - const std::vector >& vals = v.second; - if(vals.size()) - { - ss << "amount: " << v.first << ENDL; - for(size_t i = 0; i != vals.size(); i++) - ss << "\t" << vals[i].first << ": " << vals[i].second << ENDL; - } - } - if(file_io_utils::save_string_to_file(file, ss.str())) - { - LOG_PRINT_L0("Current outputs index writen to file: " << file); - }else - { - LOG_PRINT_L0("Failed to write current outputs index to file: " << file); - } -} -//------------------------------------------------------------------ -bool blockchain_storage::find_blockchain_supplement(const std::list& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(!find_blockchain_supplement(qblock_ids, resp.start_height)) - return false; - - resp.total_height = get_current_blockchain_height(); - size_t count = 0; - for(size_t i = resp.start_height; i != m_blocks.size() && count < BLOCKS_IDS_SYNCHRONIZING_DEFAULT_COUNT; i++, count++) - resp.m_block_ids.push_back(get_block_hash(m_blocks[i].bl)); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(!find_blockchain_supplement(qblock_ids, start_height)) - return false; - - total_height = get_current_blockchain_height(); - size_t count = 0; - for(size_t i = start_height; i != m_blocks.size() && count < max_count; i++, count++) - { - blocks.resize(blocks.size()+1); - blocks.back().first = m_blocks[i].bl; - std::list mis; - get_transactions(m_blocks[i].bl.tx_hashes, blocks.back().second, mis); - CHECK_AND_ASSERT_MES(!mis.size(), false, "internal error, transaction from block not found"); - } - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::add_block_as_invalid(const block& bl, const crypto::hash& h) -{ - block_extended_info bei = AUTO_VAL_INIT(bei); - bei.bl = bl; - return add_block_as_invalid(bei, h); -} -//------------------------------------------------------------------ -bool blockchain_storage::add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - auto i_res = m_invalid_blocks.insert(std::map::value_type(h, bei)); - CHECK_AND_ASSERT_MES(i_res.second, false, "at insertion invalid by tx returned status existed"); - LOG_PRINT_L0("BLOCK ADDED AS INVALID: " << h << ENDL << ", prev_id=" << bei.bl.prev_id << ", m_invalid_blocks count=" << m_invalid_blocks.size()); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::have_block(const crypto::hash& id) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(m_blocks_index.count(id)) - return true; - if(m_alternative_chains.count(id)) - return true; - /*if(m_orphaned_blocks.get().count(id)) - return true;*/ - - /*if(m_orphaned_by_tx.count(id)) - return true;*/ - if(m_invalid_blocks.count(id)) - return true; - - return false; -} -//------------------------------------------------------------------ -bool blockchain_storage::handle_block_to_main_chain(const block& bl, block_verification_context& bvc) -{ - crypto::hash id = get_block_hash(bl); - return handle_block_to_main_chain(bl, id, bvc); -} -//------------------------------------------------------------------ -bool blockchain_storage::push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector& global_indexes) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - size_t i = 0; - BOOST_FOREACH(const auto& ot, tx.vout) - { - outputs_container::mapped_type& amount_index = m_outputs[ot.amount]; - amount_index.push_back(std::pair(tx_id, i)); - global_indexes.push_back(amount_index.size()-1); - ++i; - } - return true; -} -//------------------------------------------------------------------ -size_t blockchain_storage::get_total_transactions() -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - return m_transactions.size(); -} -//------------------------------------------------------------------ -bool blockchain_storage::get_outs(uint64_t amount, std::list& pkeys) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - auto it = m_outputs.find(amount); - if(it == m_outputs.end()) - return true; - - BOOST_FOREACH(const auto& out_entry, it->second) - { - auto tx_it = m_transactions.find(out_entry.first); - CHECK_AND_ASSERT_MES(tx_it != m_transactions.end(), false, "transactions outs global index consistency broken: wrong tx id in index"); - CHECK_AND_ASSERT_MES(tx_it->second.tx.vout.size() > out_entry.second, false, "transactions outs global index consistency broken: index in tx_outx more then size"); - CHECK_AND_ASSERT_MES(tx_it->second.tx.vout[out_entry.second].target.type() == typeid(txout_to_key), false, "transactions outs global index consistency broken: index in tx_outx more then size"); - pkeys.push_back(boost::get(tx_it->second.tx.vout[out_entry.second].target).key); - } - - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - size_t i = tx.vout.size()-1; - BOOST_REVERSE_FOREACH(const auto& ot, tx.vout) - { - auto it = m_outputs.find(ot.amount); - CHECK_AND_ASSERT_MES(it != m_outputs.end(), false, "transactions outs global index consistency broken"); - CHECK_AND_ASSERT_MES(it->second.size(), false, "transactions outs global index: empty index for amount: " << ot.amount); - CHECK_AND_ASSERT_MES(it->second.back().first == tx_id , false, "transactions outs global index consistency broken: tx id missmatch"); - CHECK_AND_ASSERT_MES(it->second.back().second == i, false, "transactions outs global index consistency broken: in transaction index missmatch"); - it->second.pop_back(); - --i; - } - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::add_transaction_from_block(const transaction& tx, const crypto::hash& tx_id, const crypto::hash& bl_id, uint64_t bl_height) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - struct add_transaction_input_visitor: public boost::static_visitor - { - key_images_container& m_spent_keys; - const crypto::hash& m_tx_id; - const crypto::hash& m_bl_id; - add_transaction_input_visitor(key_images_container& spent_keys, const crypto::hash& tx_id, const crypto::hash& bl_id):m_spent_keys(spent_keys), m_tx_id(tx_id), m_bl_id(bl_id) - {} - bool operator()(const txin_to_key& in) const - { - const crypto::key_image& ki = in.k_image; - auto r = m_spent_keys.insert(ki); - if(!r.second) - { - //double spend detected - LOG_PRINT_L0("tx with id: " << m_tx_id << " in block id: " << m_bl_id << " have input marked as spent with key image: " << ki << ", block declined"); - return false; - } - return true; - } - - bool operator()(const txin_gen& tx) const{return true;} - bool operator()(const txin_to_script& tx) const{return false;} - bool operator()(const txin_to_scripthash& tx) const{return false;} - }; - - BOOST_FOREACH(const txin_v& in, tx.vin) - { - if(!boost::apply_visitor(add_transaction_input_visitor(m_spent_keys, tx_id, bl_id), in)) - { - LOG_ERROR("critical internal error: add_transaction_input_visitor failed. but here key_images should be shecked"); - purge_transaction_keyimages_from_blockchain(tx, false); - return false; - } - } - transaction_chain_entry ch_e; - ch_e.m_keeper_block_height = bl_height; - ch_e.tx = tx; - auto i_r = m_transactions.insert(std::pair(tx_id, ch_e)); - if(!i_r.second) - { - LOG_PRINT_L0("tx with id: " << tx_id << " in block id: " << bl_id << " already in blockchain"); - return false; - } - bool r = push_transaction_to_global_outs_index(tx, tx_id, i_r.first->second.m_global_output_indexes); - CHECK_AND_ASSERT_MES(r, false, "failed to return push_transaction_to_global_outs_index tx id " << tx_id); - LOG_PRINT_L2("Added transaction to blockchain history:" << ENDL - << "tx_id: " << tx_id << ENDL - << "inputs: " << tx.vin.size() << ", outs: " << tx.vout.size() << ", spend money: " << print_money(get_outs_money_amount(tx)) << "(fee: " << (is_coinbase(tx) ? "0[coinbase]" : print_money(get_tx_fee(tx))) << ")"); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector& indexs) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - auto it = m_transactions.find(tx_id); - if(it == m_transactions.end()) - { - LOG_PRINT_RED_L0("warning: get_tx_outputs_gindexs failed to find transaction with id = " << tx_id); - return false; - } - - CHECK_AND_ASSERT_MES(it->second.m_global_output_indexes.size(), false, "internal error: global indexes for transaction " << tx_id << " is empty"); - indexs = it->second.m_global_output_indexes; - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::check_tx_inputs(const transaction& tx, uint64_t& max_used_block_height, crypto::hash& max_used_block_id) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - bool res = check_tx_inputs(tx, &max_used_block_height); - if(!res) return false; - CHECK_AND_ASSERT_MES(max_used_block_height < m_blocks.size(), false, "internal error: max used block index=" << max_used_block_height << " is not less then blockchain size = " << m_blocks.size()); - get_block_hash(m_blocks[max_used_block_height].bl, max_used_block_id); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::have_tx_keyimges_as_spent(const transaction &tx) -{ - BOOST_FOREACH(const txin_v& in, tx.vin) - { - CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, in_to_key, true); - if(have_tx_keyimg_as_spent(in_to_key.k_image)) - return true; - } - return false; -} -//------------------------------------------------------------------ -bool blockchain_storage::check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height) -{ - 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) -{ - size_t sig_index = 0; - if(pmax_used_block_height) - *pmax_used_block_height = 0; - - BOOST_FOREACH(const auto& txin, tx.vin) - { - CHECK_AND_ASSERT_MES(txin.type() == typeid(txin_to_key), false, "wrong type id in tx input at blockchain_storage::check_tx_inputs"); - const txin_to_key& in_to_key = boost::get(txin); - - CHECK_AND_ASSERT_MES(in_to_key.key_offsets.size(), false, "empty in_to_key.key_offsets in transaction with id " << get_transaction_hash(tx)); - - if(have_tx_keyimg_as_spent(in_to_key.k_image)) - { - LOG_PRINT_L1("Key image already spent in blockchain: " << string_tools::pod_to_hex(in_to_key.k_image)); - return false; - } - - CHECK_AND_ASSERT_MES(sig_index < tx.signatures.size(), false, "wrong transaction: not signature entry for input with index= " << sig_index); - if(!check_tx_input(in_to_key, tx_prefix_hash, tx.signatures[sig_index], pmax_used_block_height)) - { - LOG_PRINT_L0("Failed to check ring signature for tx " << get_transaction_hash(tx)); - return false; - } - - sig_index++; - } - - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::is_tx_spendtime_unlocked(uint64_t unlock_time) -{ - if(unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) - { - //interpret as block index - if(get_current_blockchain_height()-1 + CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_BLOCKS >= unlock_time) - return true; - else - return false; - }else - { - //interpret as time - uint64_t current_time = static_cast(time(NULL)); - if(current_time + CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS >= unlock_time) - return true; - else - return false; - } - return false; -} -//------------------------------------------------------------------ -bool blockchain_storage::check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector& sig, uint64_t* pmax_related_block_height) -{ - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - struct outputs_visitor - { - std::vector& m_results_collector; - blockchain_storage& m_bch; - outputs_visitor(std::vector& results_collector, blockchain_storage& bch):m_results_collector(results_collector), m_bch(bch) - {} - bool handle_output(const transaction& tx, const tx_out& out) - { - //check tx unlock time - if(!m_bch.is_tx_spendtime_unlocked(tx.unlock_time)) - { - LOG_PRINT_L0("One of outputs for one of inputs have wrong tx.unlock_time = " << tx.unlock_time); - return false; - } - - if(out.target.type() != typeid(txout_to_key)) - { - LOG_PRINT_L0("Output have wrong type id, which=" << out.target.which()); - return false; - } - - m_results_collector.push_back(&boost::get(out.target).key); - return true; - } - }; - - //check ring signature - std::vector output_keys; - outputs_visitor vi(output_keys, *this); - if(!scan_outputkeys_for_indexes(txin, vi, pmax_related_block_height)) - { - LOG_PRINT_L0("Failed to get output keys for tx with amount = " << print_money(txin.amount) << " and count indexes " << txin.key_offsets.size()); - return false; - } - - if(txin.key_offsets.size() != output_keys.size()) - { - LOG_PRINT_L0("Output keys for tx with amount = " << txin.amount << " and count indexes " << txin.key_offsets.size() << " returned wrong keys count " << output_keys.size()); - return false; - } - CHECK_AND_ASSERT_MES(sig.size() == output_keys.size(), false, "internal error: tx signatures count=" << sig.size() << " mismatch with outputs keys count for inputs=" << output_keys.size()); - if(m_is_in_checkpoint_zone) - return true; - return crypto::check_ring_signature(tx_prefix_hash, txin.k_image, output_keys, sig.data()); -} -//------------------------------------------------------------------ -uint64_t blockchain_storage::get_adjusted_time() -{ - //TODO: add collecting median time - return time(NULL); -} -//------------------------------------------------------------------ -bool blockchain_storage::check_block_timestamp_main(const block& b) -{ - if(b.timestamp > get_adjusted_time() + CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT) - { - LOG_PRINT_L0("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than adjusted time + 2 hours"); - return false; - } - - std::vector timestamps; - size_t offset = m_blocks.size() <= BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW ? 0: m_blocks.size()- BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW; - for(;offset!= m_blocks.size(); ++offset) - timestamps.push_back(m_blocks[offset].bl.timestamp); - - return check_block_timestamp(std::move(timestamps), b); -} -//------------------------------------------------------------------ -bool blockchain_storage::check_block_timestamp(std::vector timestamps, const block& b) -{ - if(timestamps.size() < BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW) - return true; - - uint64_t median_ts = epee::misc_utils::median(timestamps); - - if(b.timestamp < median_ts) - { - LOG_PRINT_L0("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", less than median of last " << BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW << " blocks, " << median_ts); - return false; - } - - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypto::hash& id, block_verification_context& bvc) -{ - TIME_MEASURE_START(block_processing_time); - CRITICAL_REGION_LOCAL(m_blockchain_lock); - if(bl.prev_id != get_tail_id()) - { - LOG_PRINT_L0("Block with id: " << id << ENDL - << "have wrong prev_id: " << bl.prev_id << ENDL - << "expected: " << get_tail_id()); - return false; - } - - if(!check_block_timestamp_main(bl)) - { - LOG_PRINT_L0("Block with id: " << id << ENDL - << "have invalid timestamp: " << bl.timestamp); - //add_block_as_invalid(bl, id);//do not add blocks to invalid storage befor proof of work check was passed - bvc.m_verifivation_failed = true; - return false; - } - - //check proof of work - TIME_MEASURE_START(target_calculating_time); - difficulty_type current_diffic = get_difficulty_for_next_block(); - CHECK_AND_ASSERT_MES(current_diffic, false, "!!!!!!!!! difficulty overhead !!!!!!!!!"); - TIME_MEASURE_FINISH(target_calculating_time); - TIME_MEASURE_START(longhash_calculating_time); - crypto::hash proof_of_work = null_hash; - if(!m_checkpoints.is_in_checkpoint_zone(get_current_blockchain_height())) - { - proof_of_work = get_block_longhash(bl, m_blocks.size()); - - if(!check_hash(proof_of_work, current_diffic)) - { - LOG_PRINT_L0("Block with id: " << id << ENDL - << "have not enough proof of work: " << proof_of_work << ENDL - << "nexpected difficulty: " << current_diffic ); - bvc.m_verifivation_failed = true; - return false; - } - }else - { - if(!m_checkpoints.check_block(get_current_blockchain_height(), id)) - { - LOG_ERROR("CHECKPOINT VALIDATION FAILED"); - bvc.m_verifivation_failed = true; - return false; - } - } - TIME_MEASURE_FINISH(longhash_calculating_time); - - if(!prevalidate_miner_transaction(bl, m_blocks.size())) - { - LOG_PRINT_L0("Block with id: " << id - << " failed to pass prevalidation"); - bvc.m_verifivation_failed = true; - return false; - } - size_t coinbase_blob_size = get_object_blobsize(bl.miner_tx); - size_t cumulative_block_size = coinbase_blob_size; - //process transactions - if(!add_transaction_from_block(bl.miner_tx, get_transaction_hash(bl.miner_tx), id, get_current_blockchain_height())) - { - LOG_PRINT_L0("Block with id: " << id << " failed to add transaction to blockchain storage"); - bvc.m_verifivation_failed = true; - return false; - } - size_t tx_processed_count = 0; - uint64_t fee_summary = 0; - BOOST_FOREACH(const crypto::hash& tx_id, bl.tx_hashes) - { - transaction tx; - size_t blob_size = 0; - uint64_t fee = 0; - if(!m_tx_pool.take_tx(tx_id, tx, blob_size, fee)) - { - LOG_PRINT_L0("Block with id: " << id << "have at least one unknown transaction with id: " << tx_id); - purge_block_data_from_blockchain(bl, tx_processed_count); - //add_block_as_invalid(bl, id); - bvc.m_verifivation_failed = true; - return false; - } - if(!check_tx_inputs(tx)) - { - LOG_PRINT_L0("Block with id: " << id << "have at least one transaction (id: " << tx_id << ") with wrong inputs."); - cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc); - bool add_res = m_tx_pool.add_tx(tx, tvc, true); - CHECK_AND_ASSERT_MES2(add_res, "handle_block_to_main_chain: failed to add transaction back to transaction pool"); - purge_block_data_from_blockchain(bl, tx_processed_count); - add_block_as_invalid(bl, id); - LOG_PRINT_L0("Block with id " << id << " added as invalid becouse of wrong inputs in transactions"); - bvc.m_verifivation_failed = true; - return false; - } - - if(!add_transaction_from_block(tx, tx_id, id, get_current_blockchain_height())) - { - LOG_PRINT_L0("Block with id: " << id << " failed to add transaction to blockchain storage"); - cryptonote::tx_verification_context tvc = AUTO_VAL_INIT(tvc); - bool add_res = m_tx_pool.add_tx(tx, tvc, true); - CHECK_AND_ASSERT_MES2(add_res, "handle_block_to_main_chain: failed to add transaction back to transaction pool"); - purge_block_data_from_blockchain(bl, tx_processed_count); - bvc.m_verifivation_failed = true; - return false; - } - fee_summary += fee; - cumulative_block_size += blob_size; - ++tx_processed_count; - } - uint64_t base_reward = 0; - uint64_t already_generated_coins = m_blocks.size() ? m_blocks.back().already_generated_coins:0; - if(!validate_miner_transaction(bl, cumulative_block_size, fee_summary, base_reward, already_generated_coins)) - { - LOG_PRINT_L0("Block with id: " << id - << " have wrong miner transaction"); - purge_block_data_from_blockchain(bl, tx_processed_count); - bvc.m_verifivation_failed = true; - return false; - } - - - block_extended_info bei = boost::value_initialized(); - bei.bl = bl; - bei.block_cumulative_size = cumulative_block_size; - bei.cumulative_difficulty = current_diffic; - bei.already_generated_coins = already_generated_coins + base_reward; - if(m_blocks.size()) - bei.cumulative_difficulty += m_blocks.back().cumulative_difficulty; - - bei.height = m_blocks.size(); - - auto ind_res = m_blocks_index.insert(std::pair(id, bei.height)); - if(!ind_res.second) - { - LOG_ERROR("block with id: " << id << " already in block indexes"); - purge_block_data_from_blockchain(bl, tx_processed_count); - bvc.m_verifivation_failed = true; - return false; - } - - m_blocks.push_back(bei); - update_next_comulative_size_limit(); - TIME_MEASURE_FINISH(block_processing_time); - LOG_PRINT_L1("+++++ BLOCK SUCCESSFULLY ADDED" << ENDL << "id:\t" << id - << ENDL << "PoW:\t" << proof_of_work - << ENDL << "HEIGHT " << bei.height << ", difficulty:\t" << current_diffic - << ENDL << "block reward: " << print_money(fee_summary + base_reward) << "(" << print_money(base_reward) << " + " << print_money(fee_summary) - << "), coinbase_blob_size: " << coinbase_blob_size << ", cumulative size: " << cumulative_block_size - << ", " << block_processing_time << "("<< target_calculating_time << "/" << longhash_calculating_time << ")ms"); - - bvc.m_added_to_main_chain = true; - /*if(!m_orphanes_reorganize_in_work) - review_orphaned_blocks_with_new_block_id(id, true);*/ - - m_tx_pool.on_blockchain_inc(bei.height, id); - //LOG_PRINT_L0("BLOCK: " << ENDL << "" << dump_obj_as_json(bei.bl)); - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::update_next_comulative_size_limit() -{ - std::vector sz; - get_last_n_blocks_sizes(sz, CRYPTONOTE_REWARD_BLOCKS_WINDOW); - - uint64_t median = misc_utils::median(sz); - if(median <= CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE) - median = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE; - - m_current_block_cumul_sz_limit = median*2; - return true; -} -//------------------------------------------------------------------ -bool blockchain_storage::add_new_block(const block& bl_, block_verification_context& bvc) -{ - //copy block here to let modify block.target - block bl = bl_; - crypto::hash id = get_block_hash(bl); - CRITICAL_REGION_LOCAL(m_tx_pool);//to avoid deadlock lets lock tx_pool for whole add/reorganize process - CRITICAL_REGION_LOCAL1(m_blockchain_lock); - if(have_block(id)) - { - LOG_PRINT_L3("block with id = " << id << " already exists"); - bvc.m_already_exists = true; - return false; - } - - //check that block refers to chain tail - if(!(bl.prev_id == get_tail_id())) - { - //chain switching or wrong block - bvc.m_added_to_main_chain = false; - return handle_alternative_block(bl, id, bvc); - //never relay alternative blocks - } - - return handle_block_to_main_chain(bl, id, bvc); -} \ No newline at end of file diff --git a/src/cryptonote_core/blockchain_storage.h b/src/cryptonote_core/blockchain_storage.h deleted file mode 100644 index 1ea5e29..0000000 --- a/src/cryptonote_core/blockchain_storage.h +++ /dev/null @@ -1,325 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tx_pool.h" -#include "cryptonote_basic.h" -#include "common/util.h" -#include "cryptonote_protocol/cryptonote_protocol_defs.h" -#include "rpc/core_rpc_server_commands_defs.h" -#include "difficulty.h" -#include "cryptonote_core/cryptonote_format_utils.h" -#include "verification_context.h" -#include "crypto/hash.h" -#include "checkpoints.h" - -namespace cryptonote -{ - - /************************************************************************/ - /* */ - /************************************************************************/ - class blockchain_storage - { - public: - struct transaction_chain_entry - { - transaction tx; - uint64_t m_keeper_block_height; - size_t m_blob_size; - std::vector m_global_output_indexes; - }; - - struct block_extended_info - { - block bl; - uint64_t height; - size_t block_cumulative_size; - difficulty_type cumulative_difficulty; - uint64_t already_generated_coins; - }; - - blockchain_storage(tx_memory_pool& tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false) - {}; - - bool init() { return init(tools::get_default_data_dir()); } - bool init(const std::string& config_folder); - bool deinit(); - - 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& blocks, std::list& txs); - bool get_blocks(uint64_t start_offset, size_t count, std::list& blocks); - bool get_alternative_blocks(std::list& 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 &main, std::list &alt, std::list &invalid); - - template - 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); - - template - bool scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height = NULL); - - 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(); - 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& pkeys); - bool get_short_chain_history(std::list& ids); - bool find_blockchain_supplement(const std::list& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp); - bool find_blockchain_supplement(const std::list& qblock_ids, uint64_t& starter_offset); - bool find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count); - 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& sz, size_t count); - bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector& indexs); - bool store_blockchain(); - bool check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector& 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); - - template - bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) - { - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - BOOST_FOREACH(const auto& bl_id, block_ids) - { - auto it = m_blocks_index.find(bl_id); - if(it == m_blocks_index.end()) - missed_bs.push_back(bl_id); - else - { - CHECK_AND_ASSERT_MES(it->second < m_blocks.size(), false, "Internal error: bl_id=" << string_tools::pod_to_hex(bl_id) - << " have index record with offset="<second<< ", bigger then m_blocks.size()=" << m_blocks.size()); - blocks.push_back(m_blocks[it->second].bl); - } - } - return true; - } - - template - bool get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) - { - CRITICAL_REGION_LOCAL(m_blockchain_lock); - - BOOST_FOREACH(const auto& tx_id, txs_ids) - { - auto it = m_transactions.find(tx_id); - if(it == m_transactions.end()) - { - transaction tx; - if(!m_tx_pool.get_transaction(tx_id, tx)) - missed_txs.push_back(tx_id); - else - txs.push_back(tx); - } - else - txs.push_back(it->second.tx); - } - return true; - } - //debug functions - void print_blockchain(uint64_t start_index, uint64_t end_index); - void print_blockchain_index(); - void print_blockchain_outs(const std::string& file); - - private: - typedef std::unordered_map blocks_by_id_index; - typedef std::unordered_map transactions_container; - typedef std::unordered_set key_images_container; - typedef std::vector blocks_container; - typedef std::unordered_map blocks_ext_by_hash; - typedef std::unordered_map blocks_by_hash; - typedef std::map>> outputs_container; //crypto::hash - tx hash, size_t - index of out in transaction - - tx_memory_pool& m_tx_pool; - critical_section m_blockchain_lock; // TODO: add here reader/writer lock - - // main chain - blocks_container m_blocks; // height -> block_extended_info - blocks_by_id_index m_blocks_index; // crypto::hash -> height - transactions_container m_transactions; - key_images_container m_spent_keys; - size_t m_current_block_cumul_sz_limit; - - - // all alternative chains - blocks_ext_by_hash m_alternative_chains; // crypto::hash -> block_extended_info - - // some invalid blocks - blocks_ext_by_hash m_invalid_blocks; // crypto::hash -> block_extended_info - outputs_container m_outputs; - - - std::string m_config_folder; - checkpoints m_checkpoints; - std::atomic m_is_in_checkpoint_zone; - std::atomic m_is_blockchain_storing; - - bool switch_to_alternative_blockchain(std::list& alt_chain); - bool pop_block_from_blockchain(); - bool purge_block_data_from_blockchain(const block& b, size_t processed_tx_count); - bool purge_transaction_from_blockchain(const crypto::hash& tx_id); - bool purge_transaction_keyimages_from_blockchain(const transaction& tx, bool strict_check); - - 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& 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); - bool rollback_blockchain_switching(std::list& 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& global_indexes); - bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id); - bool get_last_n_blocks_sizes(std::vector& sz, size_t count); - bool add_out_to_get_random_outs(std::vector >& 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 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 >& amount_outs); - bool check_block_timestamp_main(const block& b); - bool check_block_timestamp(std::vector timestamps, const block& b); - uint64_t get_adjusted_time(); - bool complete_timestamps_vector(uint64_t start_height, std::vector& timestamps); - bool update_next_comulative_size_limit(); - }; - - - /************************************************************************/ - /* */ - /************************************************************************/ - - #define CURRENT_BLOCKCHAIN_STORAGE_ARCHIVE_VER 12 - - template - void blockchain_storage::serialize(archive_t & ar, const unsigned int version) - { - if(version < 11) - return; - CRITICAL_REGION_LOCAL(m_blockchain_lock); - ar & m_blocks; - ar & m_blocks_index; - ar & m_transactions; - ar & m_spent_keys; - ar & m_alternative_chains; - ar & m_outputs; - ar & m_invalid_blocks; - ar & m_current_block_cumul_sz_limit; - /*serialization bug workaround*/ - if(version > 11) - { - uint64_t total_check_count = m_blocks.size() + m_blocks_index.size() + m_transactions.size() + m_spent_keys.size() + m_alternative_chains.size() + m_outputs.size() + m_invalid_blocks.size() + m_current_block_cumul_sz_limit; - if(archive_t::is_saving::value) - { - ar & total_check_count; - }else - { - uint64_t total_check_count_loaded = 0; - ar & total_check_count_loaded; - if(total_check_count != total_check_count_loaded) - { - LOG_ERROR("Blockchain storage data corruption detected. total_count loaded from file = " << total_check_count_loaded << ", expected = " << total_check_count); - - LOG_PRINT_L0("Blockchain storage:" << ENDL << - "m_blocks: " << m_blocks.size() << ENDL << - "m_blocks_index: " << m_blocks_index.size() << ENDL << - "m_transactions: " << m_transactions.size() << ENDL << - "m_spent_keys: " << m_spent_keys.size() << ENDL << - "m_alternative_chains: " << m_alternative_chains.size() << ENDL << - "m_outputs: " << m_outputs.size() << ENDL << - "m_invalid_blocks: " << m_invalid_blocks.size() << ENDL << - "m_current_block_cumul_sz_limit: " << m_current_block_cumul_sz_limit); - - throw std::runtime_error("Blockchain data corruption"); - } - } - } - - - LOG_PRINT_L2("Blockchain storage:" << ENDL << - "m_blocks: " << m_blocks.size() << ENDL << - "m_blocks_index: " << m_blocks_index.size() << ENDL << - "m_transactions: " << m_transactions.size() << ENDL << - "m_spent_keys: " << m_spent_keys.size() << ENDL << - "m_alternative_chains: " << m_alternative_chains.size() << ENDL << - "m_outputs: " << m_outputs.size() << ENDL << - "m_invalid_blocks: " << m_invalid_blocks.size() << ENDL << - "m_current_block_cumul_sz_limit: " << m_current_block_cumul_sz_limit); - } - - //------------------------------------------------------------------ - template - bool blockchain_storage::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height) - { - CRITICAL_REGION_LOCAL(m_blockchain_lock); - auto it = m_outputs.find(tx_in_to_key.amount); - if(it == m_outputs.end() || !tx_in_to_key.key_offsets.size()) - return false; - - std::vector absolute_offsets = relative_output_offsets_to_absolute(tx_in_to_key.key_offsets); - - - std::vector >& amount_outs_vec = it->second; - size_t count = 0; - BOOST_FOREACH(uint64_t i, absolute_offsets) - { - if(i >= amount_outs_vec.size() ) - { - 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); - CHECK_AND_ASSERT_MES(tx_it != m_transactions.end(), false, "Wrong transaction id in output indexes: " <second.tx.vout.size(), false, - "Wrong index in transaction outputs: " << amount_outs_vec[i].second << ", expected less then " << tx_it->second.tx.vout.size()); - if(!vis.handle_output(tx_it->second.tx, tx_it->second.tx.vout[amount_outs_vec[i].second])) - { - LOG_PRINT_L0("Failed to handle_output for output no = " << count << ", with absolute offset " << i); - return false; - } - if(count++ == absolute_offsets.size()-1 && pmax_related_block_height) - { - if(*pmax_related_block_height < tx_it->second.m_keeper_block_height) - *pmax_related_block_height = tx_it->second.m_keeper_block_height; - } - } - - return true; - } -} - - - -BOOST_CLASS_VERSION(cryptonote::blockchain_storage, CURRENT_BLOCKCHAIN_STORAGE_ARCHIVE_VER) diff --git a/src/cryptonote_core/blockchain_storage_boost_serialization.h b/src/cryptonote_core/blockchain_storage_boost_serialization.h deleted file mode 100644 index 6aa06e8..0000000 --- a/src/cryptonote_core/blockchain_storage_boost_serialization.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -namespace boost -{ - namespace serialization - { - - - template - void serialize(archive_t & ar, cryptonote::blockchain_storage::transaction_chain_entry& te, const unsigned int version) - { - ar & te.tx; - ar & te.m_keeper_block_height; - ar & te.m_blob_size; - ar & te.m_global_output_indexes; - } - - template - void serialize(archive_t & ar, cryptonote::blockchain_storage::block_extended_info& ei, const unsigned int version) - { - ar & ei.bl; - ar & ei.height; - ar & ei.cumulative_difficulty; - ar & ei.block_cumulative_size; - ar & ei.already_generated_coins; - } - - } -} diff --git a/src/cryptonote_core/checkpoints.cpp b/src/cryptonote_core/checkpoints.cpp deleted file mode 100644 index 54c2f3a..0000000 --- a/src/cryptonote_core/checkpoints.cpp +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "include_base_utils.h" -using namespace epee; - -#include "checkpoints.h" - -namespace cryptonote -{ - //--------------------------------------------------------------------------- - checkpoints::checkpoints() - { - } - //--------------------------------------------------------------------------- - bool checkpoints::add_checkpoint(uint64_t height, const std::string& hash_str) - { - crypto::hash h = null_hash; - bool r = epee::string_tools::parse_tpod_from_hex_string(hash_str, h); - CHECK_AND_ASSERT_MES(r, false, "WRONG HASH IN CHECKPOINTS!!!"); - CHECK_AND_ASSERT_MES(0 == m_points.count(height), false, "WRONG HASH IN CHECKPOINTS!!!"); - m_points[height] = h; - return true; - } - //--------------------------------------------------------------------------- - bool checkpoints::is_in_checkpoint_zone(uint64_t height) const - { - return !m_points.empty() && (height <= (--m_points.end())->first); - } - //--------------------------------------------------------------------------- - bool checkpoints::check_block(uint64_t height, const crypto::hash& h) const - { - auto it = m_points.find(height); - if(it == m_points.end()) - return true; - - if(it->second == h) - { - LOG_PRINT_GREEN("CHECKPOINT PASSED FOR HEIGHT " << height << " " << h, LOG_LEVEL_0); - return true; - }else - { - LOG_ERROR("CHECKPOINT FAILED FOR HEIGHT " << height << ". EXPECTED HASH: " << it->second << ", FETCHED HASH: " << h); - return false; - } - } -} diff --git a/src/cryptonote_core/checkpoints.h b/src/cryptonote_core/checkpoints.h deleted file mode 100644 index 20014b1..0000000 --- a/src/cryptonote_core/checkpoints.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once -#include -#include "cryptonote_basic_impl.h" - - -namespace cryptonote -{ - class checkpoints - { - public: - checkpoints(); - bool add_checkpoint(uint64_t height, const std::string& hash_str); - bool is_in_checkpoint_zone(uint64_t height) const; - bool check_block(uint64_t height, const crypto::hash& h) const; - private: - std::map m_points; - }; -} diff --git a/src/cryptonote_core/checkpoints_create.h b/src/cryptonote_core/checkpoints_create.h deleted file mode 100644 index 32d1583..0000000 --- a/src/cryptonote_core/checkpoints_create.h +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -#include "checkpoints.h" -#include "misc_log_ex.h" - -#define ADD_CHECKPOINT(h, hash) CHECK_AND_ASSERT(checkpoints.add_checkpoint(h, hash), false); - -namespace cryptonote { - inline bool create_checkpoints(cryptonote::checkpoints& checkpoints) - { - // Checkpointing disabled until we can make the client not fast-sync - // without checking PoW at some point. Otherwise we may be exposed - // to blockchain corruption attacks. Need to investigate this further. - // 8-5-14 - // ADD_CHECKPOINT(22231, "7cb10e29d67e1c069e6e11b17d30b809724255fee2f6868dc14cfc6ed44dfb25"); - // ADD_CHECKPOINT(29556, "53c484a8ed91e4da621bb2fa88106dbde426fe90d7ef07b9c1e5127fb6f3a7f6"); - return true; - } -} diff --git a/src/cryptonote_core/connection_context.h b/src/cryptonote_core/connection_context.h deleted file mode 100644 index 53cac99..0000000 --- a/src/cryptonote_core/connection_context.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once -#include -#include -#include "net/net_utils_base.h" -#include "copyable_atomic.h" - -namespace cryptonote -{ - - struct cryptonote_connection_context: public epee::net_utils::connection_context_base - { - - enum state - { - state_befor_handshake = 0, //default state - state_synchronizing, - state_idle, - state_normal - }; - - state m_state; - std::list m_needed_objects; - std::unordered_set m_requested_objects; - uint64_t m_remote_blockchain_height; - uint64_t m_last_response_height; - epee::copyable_atomic m_callback_request_count; //in debug purpose: problem with double callback rise - //size_t m_score; TODO: add score calculations - }; - - inline std::string get_protocol_state_string(cryptonote_connection_context::state s) - { - switch (s) - { - case cryptonote_connection_context::state_befor_handshake: - return "state_befor_handshake"; - case cryptonote_connection_context::state_synchronizing: - return "state_synchronizing"; - case cryptonote_connection_context::state_idle: - return "state_idle"; - case cryptonote_connection_context::state_normal: - return "state_normal"; - default: - return "unknown"; - } - } - -} diff --git a/src/cryptonote_core/cryptonote_basic_impl.cpp b/src/cryptonote_core/cryptonote_basic_impl.cpp deleted file mode 100644 index 876b966..0000000 --- a/src/cryptonote_core/cryptonote_basic_impl.cpp +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#include "include_base_utils.h" -using namespace epee; - -#include "cryptonote_basic_impl.h" -#include "string_tools.h" -#include "serialization/binary_utils.h" -#include "serialization/vector.h" -#include "cryptonote_format_utils.h" -#include "cryptonote_config.h" -#include "misc_language.h" -#include "common/base58.h" -#include "crypto/hash.h" -#include "common/int-util.h" - -namespace cryptonote { - - /************************************************************************/ - /* Cryptonote helper functions */ - /************************************************************************/ - //----------------------------------------------------------------------------------------------- - size_t get_max_block_size() - { - return CRYPTONOTE_MAX_BLOCK_SIZE; - } - //----------------------------------------------------------------------------------------------- - size_t get_max_tx_size() - { - return CRYPTONOTE_MAX_TX_SIZE; - } - //----------------------------------------------------------------------------------------------- - bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward) { - uint64_t base_reward = (MONEY_SUPPLY - already_generated_coins) >> EMISSION_SPEED_FACTOR; - - //make it soft - if (median_size < CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE) { - median_size = CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE; - } - - if (current_block_size <= median_size) { - reward = base_reward; - return true; - } - - if(current_block_size > 2 * median_size) { - LOG_PRINT_L4("Block cumulative size is too big: " << current_block_size << ", expected less than " << 2 * median_size); - return false; - } - - assert(median_size < std::numeric_limits::max()); - assert(current_block_size < std::numeric_limits::max()); - - uint64_t product_hi; - uint64_t product_lo = mul128(base_reward, current_block_size * (2 * median_size - current_block_size), &product_hi); - - uint64_t reward_hi; - uint64_t reward_lo; - div128_32(product_hi, product_lo, static_cast(median_size), &reward_hi, &reward_lo); - div128_32(reward_hi, reward_lo, static_cast(median_size), &reward_hi, &reward_lo); - assert(0 == reward_hi); - assert(reward_lo < base_reward); - - reward = reward_lo; - return true; - } - //------------------------------------------------------------------------------------ - uint8_t get_account_address_checksum(const public_address_outer_blob& bl) - { - const unsigned char* pbuf = reinterpret_cast(&bl); - uint8_t summ = 0; - for(size_t i = 0; i!= sizeof(public_address_outer_blob)-1; i++) - summ += pbuf[i]; - - return summ; - } - //----------------------------------------------------------------------- - std::string get_account_address_as_str(const account_public_address& adr) - { - return tools::base58::encode_addr(CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(adr)); - } - //----------------------------------------------------------------------- - bool is_coinbase(const transaction& tx) - { - if(tx.vin.size() != 1) - return false; - - if(tx.vin[0].type() != typeid(txin_gen)) - return false; - - return true; - } - //----------------------------------------------------------------------- - bool get_account_address_from_str(account_public_address& adr, const std::string& str) - { - if (2 * sizeof(public_address_outer_blob) != str.size()) - { - blobdata data; - uint64_t prefix; - if (!tools::base58::decode_addr(str, prefix, data)) - { - LOG_PRINT_L1("Invalid address format"); - return false; - } - - if (CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX != prefix) - { - LOG_PRINT_L1("Wrong address prefix: " << prefix << ", expected " << CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX); - return false; - } - - if (!::serialization::parse_binary(data, adr)) - { - LOG_PRINT_L1("Account public address keys can't be parsed"); - return false; - } - - if (!crypto::check_key(adr.m_spend_public_key) || !crypto::check_key(adr.m_view_public_key)) - { - LOG_PRINT_L1("Failed to validate address keys"); - return false; - } - } - else - { - // Old address format - std::string buff; - if(!string_tools::parse_hexstr_to_binbuff(str, buff)) - return false; - - if(buff.size()!=sizeof(public_address_outer_blob)) - { - LOG_PRINT_L1("Wrong public address size: " << buff.size() << ", expected size: " << sizeof(public_address_outer_blob)); - return false; - } - - public_address_outer_blob blob = *reinterpret_cast(buff.data()); - - - if(blob.m_ver > CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER) - { - LOG_PRINT_L1("Unknown version of public address: " << blob.m_ver << ", expected " << CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER); - return false; - } - - if(blob.check_sum != get_account_address_checksum(blob)) - { - LOG_PRINT_L1("Wrong public address checksum"); - return false; - } - - //we success - adr = blob.m_address; - } - - return true; - } - - bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b) { - return cryptonote::get_transaction_hash(a) == cryptonote::get_transaction_hash(b); - } - - bool operator ==(const cryptonote::block& a, const cryptonote::block& b) { - return cryptonote::get_block_hash(a) == cryptonote::get_block_hash(b); - } -} - -//-------------------------------------------------------------------------------- -bool parse_hash256(const std::string str_hash, crypto::hash& hash) -{ - std::string buf; - bool res = epee::string_tools::parse_hexstr_to_binbuff(str_hash, buf); - if (!res || buf.size() != sizeof(crypto::hash)) - { - std::cout << "invalid hash format: <" << str_hash << '>' << std::endl; - return false; - } - else - { - buf.copy(reinterpret_cast(&hash), sizeof(crypto::hash)); - return true; - } -} diff --git a/src/cryptonote_core/cryptonote_basic_impl.h b/src/cryptonote_core/cryptonote_basic_impl.h deleted file mode 100644 index cb6fb76..0000000 --- a/src/cryptonote_core/cryptonote_basic_impl.h +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -#include "cryptonote_basic.h" -#include "crypto/crypto.h" -#include "crypto/hash.h" - - -namespace cryptonote { - /************************************************************************/ - /* */ - /************************************************************************/ - template - struct array_hasher: std::unary_function - { - std::size_t operator()(const t_array& val) const - { - return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]); - } - }; - - -#pragma pack(push, 1) - struct public_address_outer_blob - { - uint8_t m_ver; - account_public_address m_address; - uint8_t check_sum; - }; -#pragma pack (pop) - - - /************************************************************************/ - /* Cryptonote helper functions */ - /************************************************************************/ - size_t get_max_block_size(); - size_t get_max_tx_size(); - bool get_block_reward(size_t median_size, size_t current_block_size, uint64_t already_generated_coins, uint64_t &reward); - uint8_t get_account_address_checksum(const public_address_outer_blob& bl); - std::string get_account_address_as_str(const account_public_address& adr); - bool get_account_address_from_str(account_public_address& adr, const std::string& str); - bool is_coinbase(const transaction& tx); - - bool operator ==(const cryptonote::transaction& a, const cryptonote::transaction& b); - bool operator ==(const cryptonote::block& a, const cryptonote::block& b); -} - -template -std::ostream &print256(std::ostream &o, const T &v) { - return o << "<" << epee::string_tools::pod_to_hex(v) << ">"; -} - -bool parse_hash256(const std::string str_hash, crypto::hash& hash); - -namespace crypto { - inline std::ostream &operator <<(std::ostream &o, const crypto::public_key &v) { return print256(o, v); } - inline std::ostream &operator <<(std::ostream &o, const crypto::secret_key &v) { return print256(o, v); } - inline std::ostream &operator <<(std::ostream &o, const crypto::key_derivation &v) { return print256(o, v); } - inline std::ostream &operator <<(std::ostream &o, const crypto::key_image &v) { return print256(o, v); } - inline std::ostream &operator <<(std::ostream &o, const crypto::signature &v) { return print256(o, v); } - inline std::ostream &operator <<(std::ostream &o, const crypto::hash &v) { return print256(o, v); } -} diff --git a/src/cryptonote_core/cryptonote_boost_serialization.h b/src/cryptonote_core/cryptonote_boost_serialization.h deleted file mode 100644 index 9dd6912..0000000 --- a/src/cryptonote_core/cryptonote_boost_serialization.h +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include "cryptonote_basic.h" -#include "common/unordered_containers_boost_serialization.h" -#include "crypto/crypto.h" - -//namespace cryptonote { -namespace boost -{ - namespace serialization - { - - //--------------------------------------------------- - template - inline void serialize(Archive &a, crypto::public_key &x, const boost::serialization::version_type ver) - { - a & reinterpret_cast(x); - } - template - inline void serialize(Archive &a, crypto::secret_key &x, const boost::serialization::version_type ver) - { - a & reinterpret_cast(x); - } - template - inline void serialize(Archive &a, crypto::key_derivation &x, const boost::serialization::version_type ver) - { - a & reinterpret_cast(x); - } - template - inline void serialize(Archive &a, crypto::key_image &x, const boost::serialization::version_type ver) - { - a & reinterpret_cast(x); - } - - template - inline void serialize(Archive &a, crypto::signature &x, const boost::serialization::version_type ver) - { - a & reinterpret_cast(x); - } - template - inline void serialize(Archive &a, crypto::hash &x, const boost::serialization::version_type ver) - { - a & reinterpret_cast(x); - } - - template - inline void serialize(Archive &a, cryptonote::txout_to_script &x, const boost::serialization::version_type ver) - { - a & x.keys; - a & x.script; - } - - - template - inline void serialize(Archive &a, cryptonote::txout_to_key &x, const boost::serialization::version_type ver) - { - a & x.key; - } - - - template - inline void serialize(Archive &a, cryptonote::bb_txout_to_key &x, const boost::serialization::version_type ver) - { - a & x.key; - a & x.mix_attr; - } - - template - inline void serialize(Archive &a, cryptonote::txout_to_scripthash &x, const boost::serialization::version_type ver) - { - a & x.hash; - } - - template - inline void serialize(Archive &a, cryptonote::txin_gen &x, const boost::serialization::version_type ver) - { - a & x.height; - } - - template - inline void serialize(Archive &a, cryptonote::txin_to_script &x, const boost::serialization::version_type ver) - { - a & x.prev; - a & x.prevout; - a & x.sigset; - } - - template - inline void serialize(Archive &a, cryptonote::txin_to_scripthash &x, const boost::serialization::version_type ver) - { - a & x.prev; - a & x.prevout; - a & x.script; - a & x.sigset; - } - - template - inline void serialize(Archive &a, cryptonote::txin_to_key &x, const boost::serialization::version_type ver) - { - a & x.amount; - a & x.key_offsets; - a & x.k_image; - } - - template - inline void serialize(Archive &a, cryptonote::tx_out &x, const boost::serialization::version_type ver) - { - a & x.amount; - a & x.target; - } - - - template - inline void serialize(Archive &a, cryptonote::transaction &x, const boost::serialization::version_type ver) - { - a & x.version; - a & x.unlock_time; - a & x.vin; - a & x.vout; - a & x.extra; - a & x.signatures; - } - - template - inline void serialize(Archive &a, cryptonote::block &b, const boost::serialization::version_type ver) - { - a & b.major_version; - a & b.minor_version; - a & b.timestamp; - a & b.prev_id; - a & b.nonce; - //------------------ - a & b.miner_tx; - a & b.tx_hashes; - } -} -} - -//} diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp deleted file mode 100644 index a09f25d..0000000 --- a/src/cryptonote_core/cryptonote_core.cpp +++ /dev/null @@ -1,519 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#include "include_base_utils.h" -using namespace epee; - -#include -#include -#include "cryptonote_core.h" -#include "common/command_line.h" -#include "common/util.h" -#include "warnings.h" -#include "crypto/crypto.h" -#include "cryptonote_config.h" -#include "cryptonote_format_utils.h" -#include "misc_language.h" - -DISABLE_VS_WARNINGS(4355) - -namespace cryptonote -{ - - //----------------------------------------------------------------------------------------------- - core::core(i_cryptonote_protocol* pprotocol): - m_mempool(m_blockchain_storage), - m_blockchain_storage(m_mempool), - m_miner(this), - m_miner_address(boost::value_initialized()), - m_starter_message_showed(false) - { - set_cryptonote_protocol(pprotocol); - } - void core::set_cryptonote_protocol(i_cryptonote_protocol* pprotocol) - { - if(pprotocol) - m_pprotocol = pprotocol; - else - m_pprotocol = &m_protocol_stub; - } - //----------------------------------------------------------------------------------- - void core::set_checkpoints(checkpoints&& chk_pts) - { - m_blockchain_storage.set_checkpoints(std::move(chk_pts)); - } - //----------------------------------------------------------------------------------- - void core::init_options(boost::program_options::options_description& /*desc*/) - { - } - //----------------------------------------------------------------------------------------------- - bool core::handle_command_line(const boost::program_options::variables_map& vm) - { - m_config_folder = command_line::get_arg(vm, command_line::arg_data_dir); - return true; - } - //----------------------------------------------------------------------------------------------- - uint64_t core::get_current_blockchain_height() - { - return m_blockchain_storage.get_current_blockchain_height(); - } - //----------------------------------------------------------------------------------------------- - bool core::get_blockchain_top(uint64_t& height, crypto::hash& top_id) - { - top_id = m_blockchain_storage.get_tail_id(height); - return true; - } - //----------------------------------------------------------------------------------------------- - bool core::get_blocks(uint64_t start_offset, size_t count, std::list& blocks, std::list& txs) - { - return m_blockchain_storage.get_blocks(start_offset, count, blocks, txs); - } - //----------------------------------------------------------------------------------------------- - bool core::get_blocks(uint64_t start_offset, size_t count, std::list& blocks) - { - return m_blockchain_storage.get_blocks(start_offset, count, blocks); - } //----------------------------------------------------------------------------------------------- - bool core::get_transactions(const std::vector& txs_ids, std::list& txs, std::list& missed_txs) - { - return m_blockchain_storage.get_transactions(txs_ids, txs, missed_txs); - } - //----------------------------------------------------------------------------------------------- - bool core::get_transaction(const crypto::hash &h, transaction &tx) - { - std::vector ids; - ids.push_back(h); - std::list ltx; - std::list missing; - if (m_blockchain_storage.get_transactions(ids, ltx, missing)) - { - if (ltx.size() > 0) - { - tx = *ltx.begin(); - return true; - } - } - - return false; - } - //----------------------------------------------------------------------------------------------- - bool core::get_alternative_blocks(std::list& blocks) - { - return m_blockchain_storage.get_alternative_blocks(blocks); - } - //----------------------------------------------------------------------------------------------- - size_t core::get_alternative_blocks_count() - { - return m_blockchain_storage.get_alternative_blocks_count(); - } - //----------------------------------------------------------------------------------------------- - bool core::init(const boost::program_options::variables_map& vm) - { - bool r = handle_command_line(vm); - - r = m_mempool.init(m_config_folder); - CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool"); - - r = m_blockchain_storage.init(m_config_folder); - CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage"); - - r = m_miner.init(vm); - CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage"); - - return load_state_data(); - } - //----------------------------------------------------------------------------------------------- - bool core::set_genesis_block(const block& b) - { - return m_blockchain_storage.reset_and_set_genesis_block(b); - } - //----------------------------------------------------------------------------------------------- - bool core::load_state_data() - { - // may be some code later - return true; - } - //----------------------------------------------------------------------------------------------- - bool core::deinit() - { - m_miner.stop(); - m_mempool.deinit(); - m_blockchain_storage.deinit(); - return true; - } - //----------------------------------------------------------------------------------------------- - bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block) - { - tvc = boost::value_initialized(); - //want to process all transactions sequentially - CRITICAL_REGION_LOCAL(m_incoming_tx_lock); - - if(tx_blob.size() > get_max_tx_size()) - { - LOG_PRINT_L0("WRONG TRANSACTION BLOB, too big size " << tx_blob.size() << ", rejected"); - tvc.m_verifivation_failed = true; - return false; - } - - crypto::hash tx_hash = null_hash; - crypto::hash tx_prefixt_hash = null_hash; - transaction tx; - - if(!parse_tx_from_blob(tx, tx_hash, tx_prefixt_hash, tx_blob)) - { - LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to parse, rejected"); - tvc.m_verifivation_failed = true; - return false; - } - //std::cout << "!"<< tx.vin.size() << std::endl; - - if(!check_tx_syntax(tx)) - { - LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " syntax, rejected"); - tvc.m_verifivation_failed = true; - return false; - } - - if(!check_tx_semantic(tx, keeped_by_block)) - { - LOG_PRINT_L0("WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash << " semantic, rejected"); - tvc.m_verifivation_failed = true; - return false; - } - - bool r = add_new_tx(tx, tx_hash, tx_prefixt_hash, tx_blob.size(), tvc, keeped_by_block); - if(tvc.m_verifivation_failed) - {LOG_PRINT_RED_L0("Transaction verification failed: " << tx_hash);} - else if(tvc.m_verifivation_impossible) - {LOG_PRINT_RED_L0("Transaction verification impossible: " << tx_hash);} - - if(tvc.m_added_to_pool) - LOG_PRINT_L1("tx added: " << tx_hash); - return r; - } - //----------------------------------------------------------------------------------------------- - bool core::get_stat_info(core_stat_info& st_inf) - { - st_inf.mining_speed = m_miner.get_speed(); - st_inf.alternative_blocks = m_blockchain_storage.get_alternative_blocks_count(); - st_inf.blockchain_height = m_blockchain_storage.get_current_blockchain_height(); - st_inf.tx_pool_size = m_mempool.get_transactions_count(); - st_inf.top_block_id_str = epee::string_tools::pod_to_hex(m_blockchain_storage.get_tail_id()); - return true; - } - - //----------------------------------------------------------------------------------------------- - bool core::check_tx_semantic(const transaction& tx, bool keeped_by_block) - { - if(!tx.vin.size()) - { - LOG_PRINT_RED_L0("tx with empty inputs, rejected for tx id= " << get_transaction_hash(tx)); - return false; - } - - if(!check_inputs_types_supported(tx)) - { - LOG_PRINT_RED_L0("unsupported input types for tx id= " << get_transaction_hash(tx)); - return false; - } - - if(!check_outs_valid(tx)) - { - LOG_PRINT_RED_L0("tx with invalid outputs, rejected for tx id= " << get_transaction_hash(tx)); - return false; - } - - if(!check_money_overflow(tx)) - { - LOG_PRINT_RED_L0("tx have money overflow, rejected for tx id= " << get_transaction_hash(tx)); - return false; - } - - uint64_t amount_in = 0; - get_inputs_money_amount(tx, amount_in); - uint64_t amount_out = get_outs_money_amount(tx); - - if(amount_in <= amount_out) - { - LOG_PRINT_RED_L0("tx with wrong amounts: ins " << amount_in << ", outs " << amount_out << ", rejected for tx id= " << get_transaction_hash(tx)); - return false; - } - - if(!keeped_by_block && get_object_blobsize(tx) >= m_blockchain_storage.get_current_comulative_blocksize_limit() - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE) - { - LOG_PRINT_RED_L0("tx have to big size " << get_object_blobsize(tx) << ", expected not bigger than " << m_blockchain_storage.get_current_comulative_blocksize_limit() - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE); - return false; - } - - //check if tx use different key images - if(!check_tx_inputs_keyimages_diff(tx)) - { - LOG_PRINT_RED_L0("tx have to big size " << get_object_blobsize(tx) << ", expected not bigger than " << m_blockchain_storage.get_current_comulative_blocksize_limit() - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE); - return false; - } - - - return true; - } - //----------------------------------------------------------------------------------------------- - bool core::check_tx_inputs_keyimages_diff(const transaction& tx) - { - std::unordered_set ki; - BOOST_FOREACH(const auto& in, tx.vin) - { - CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false); - if(!ki.insert(tokey_in.k_image).second) - return false; - } - return true; - } - //----------------------------------------------------------------------------------------------- - bool core::add_new_tx(const transaction& tx, tx_verification_context& tvc, bool keeped_by_block) - { - crypto::hash tx_hash = get_transaction_hash(tx); - crypto::hash tx_prefix_hash = get_transaction_prefix_hash(tx); - blobdata bl; - t_serializable_object_to_blob(tx, bl); - return add_new_tx(tx, tx_hash, tx_prefix_hash, bl.size(), tvc, keeped_by_block); - } - //----------------------------------------------------------------------------------------------- - size_t core::get_blockchain_total_transactions() - { - return m_blockchain_storage.get_total_transactions(); - } - //----------------------------------------------------------------------------------------------- - bool core::get_outs(uint64_t amount, std::list& pkeys) - { - return m_blockchain_storage.get_outs(amount, pkeys); - } - //----------------------------------------------------------------------------------------------- - bool core::add_new_tx(const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block) - { - if(m_mempool.have_tx(tx_hash)) - { - LOG_PRINT_L2("tx " << tx_hash << "already have transaction in tx_pool"); - return true; - } - - if(m_blockchain_storage.have_tx(tx_hash)) - { - LOG_PRINT_L2("tx " << tx_hash << " already have transaction in blockchain"); - return true; - } - - return m_mempool.add_tx(tx, tx_hash, blob_size, tvc, keeped_by_block); - } - //----------------------------------------------------------------------------------------------- - bool core::get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce) - { - return m_blockchain_storage.create_block_template(b, adr, diffic, height, ex_nonce); - } - //----------------------------------------------------------------------------------------------- - bool core::find_blockchain_supplement(const std::list& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) - { - return m_blockchain_storage.find_blockchain_supplement(qblock_ids, resp); - } - //----------------------------------------------------------------------------------------------- - bool core::find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) - { - return m_blockchain_storage.find_blockchain_supplement(qblock_ids, blocks, total_height, start_height, max_count); - } - //----------------------------------------------------------------------------------------------- - void core::print_blockchain(uint64_t start_index, uint64_t end_index) - { - m_blockchain_storage.print_blockchain(start_index, end_index); - } - //----------------------------------------------------------------------------------------------- - void core::print_blockchain_index() - { - m_blockchain_storage.print_blockchain_index(); - } - //----------------------------------------------------------------------------------------------- - void core::print_blockchain_outs(const std::string& file) - { - m_blockchain_storage.print_blockchain_outs(file); - } - //----------------------------------------------------------------------------------------------- - bool core::get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) - { - return m_blockchain_storage.get_random_outs_for_amounts(req, res); - } - //----------------------------------------------------------------------------------------------- - bool core::get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector& indexs) - { - return m_blockchain_storage.get_tx_outputs_gindexs(tx_id, indexs); - } - //----------------------------------------------------------------------------------------------- - void core::pause_mine() - { - m_miner.pause(); - } - //----------------------------------------------------------------------------------------------- - void core::resume_mine() - { - m_miner.resume(); - } - //----------------------------------------------------------------------------------------------- - bool core::handle_block_found(block& b) - { - block_verification_context bvc = boost::value_initialized(); - m_miner.pause(); - m_blockchain_storage.add_new_block(b, bvc); - //anyway - update miner template - update_miner_block_template(); - m_miner.resume(); - - - CHECK_AND_ASSERT_MES(!bvc.m_verifivation_failed, false, "mined block failed verification"); - if(bvc.m_added_to_main_chain) - { - cryptonote_connection_context exclude_context = boost::value_initialized(); - NOTIFY_NEW_BLOCK::request arg = AUTO_VAL_INIT(arg); - arg.hop = 0; - arg.current_blockchain_height = m_blockchain_storage.get_current_blockchain_height(); - std::list missed_txs; - std::list txs; - m_blockchain_storage.get_transactions(b.tx_hashes, txs, missed_txs); - if(missed_txs.size() && m_blockchain_storage.get_block_id_by_height(get_block_height(b)) != get_block_hash(b)) - { - LOG_PRINT_L0("Block found but, seems that reorganize just happened after that, do not relay this block"); - return true; - } - CHECK_AND_ASSERT_MES(txs.size() == b.tx_hashes.size() && !missed_txs.size(), false, "cant find some transactions in found block:" << get_block_hash(b) << " txs.size()=" << txs.size() - << ", b.tx_hashes.size()=" << b.tx_hashes.size() << ", missed_txs.size()" << missed_txs.size()); - - block_to_blob(b, arg.b.block); - //pack transactions - BOOST_FOREACH(auto& tx, txs) - arg.b.txs.push_back(t_serializable_object_to_blob(tx)); - - m_pprotocol->relay_block(arg, exclude_context); - } - return bvc.m_added_to_main_chain; - } - //----------------------------------------------------------------------------------------------- - void core::on_synchronized() - { - m_miner.on_synchronized(); - } - bool core::get_backward_blocks_sizes(uint64_t from_height, std::vector& sizes, size_t count) - { - return m_blockchain_storage.get_backward_blocks_sizes(from_height, sizes, count); - } - //----------------------------------------------------------------------------------------------- - bool core::add_new_block(const block& b, block_verification_context& bvc) - { - return m_blockchain_storage.add_new_block(b, bvc); - } - //----------------------------------------------------------------------------------------------- - bool core::handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate) - { - bvc = boost::value_initialized(); - if(block_blob.size() > get_max_block_size()) - { - LOG_PRINT_L0("WRONG BLOCK BLOB, too big size " << block_blob.size() << ", rejected"); - bvc.m_verifivation_failed = true; - return false; - } - - - block b = AUTO_VAL_INIT(b); - if(!parse_and_validate_block_from_blob(block_blob, b)) - { - LOG_PRINT_L0("Failed to parse and validate new block"); - bvc.m_verifivation_failed = true; - return false; - } - add_new_block(b, bvc); - if(update_miner_blocktemplate && bvc.m_added_to_main_chain) - update_miner_block_template(); - return true; - } - //----------------------------------------------------------------------------------------------- - crypto::hash core::get_tail_id() - { - return m_blockchain_storage.get_tail_id(); - } - //----------------------------------------------------------------------------------------------- - size_t core::get_pool_transactions_count() - { - return m_mempool.get_transactions_count(); - } - //----------------------------------------------------------------------------------------------- - bool core::have_block(const crypto::hash& id) - { - return m_blockchain_storage.have_block(id); - } - //----------------------------------------------------------------------------------------------- - bool core::parse_tx_from_blob(transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash, const blobdata& blob) - { - return parse_and_validate_tx_from_blob(blob, tx, tx_hash, tx_prefix_hash); - } - //----------------------------------------------------------------------------------------------- - bool core::check_tx_syntax(const transaction& tx) - { - return true; - } - //----------------------------------------------------------------------------------------------- - bool core::get_pool_transactions(std::list& txs) - { - return m_mempool.get_transactions(txs); - } - //----------------------------------------------------------------------------------------------- - bool core::get_short_chain_history(std::list& ids) - { - return m_blockchain_storage.get_short_chain_history(ids); - } - //----------------------------------------------------------------------------------------------- - bool core::handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote_connection_context& context) - { - return m_blockchain_storage.handle_get_objects(arg, rsp); - } - //----------------------------------------------------------------------------------------------- - crypto::hash core::get_block_id_by_height(uint64_t height) - { - return m_blockchain_storage.get_block_id_by_height(height); - } - //----------------------------------------------------------------------------------------------- - bool core::get_block_by_hash(const crypto::hash &h, block &blk) { - return m_blockchain_storage.get_block_by_hash(h, blk); - } - //----------------------------------------------------------------------------------------------- - void core::get_all_known_block_ids(std::list &main, std::list &alt, std::list &invalid) { - m_blockchain_storage.get_all_known_block_ids(main, alt, invalid); - } - //----------------------------------------------------------------------------------------------- - std::string core::print_pool(bool short_format) - { - return m_mempool.print_pool(short_format); - } - //----------------------------------------------------------------------------------------------- - bool core::update_miner_block_template() - { - m_miner.on_block_chain_update(); - return true; - } - //----------------------------------------------------------------------------------------------- - bool core::on_idle() - { - if(!m_starter_message_showed) - { - LOG_PRINT_L0(ENDL << "**********************************************************************" << ENDL - << "The daemon will start synchronizing with the network. It may take up to several hours." << ENDL - << ENDL - << "You can set the level of process detailization by using command \"set_log \", where is either 0 (no details), 1 (current block height synchronized), or 2 (all details)." << ENDL - << ENDL - << "Use \"help\" command to see the list of available commands." << ENDL - << ENDL - << "Note: in case you need to interrupt the process, use \"exit\" command. Otherwise, the current progress won't be saved." << ENDL - << "**********************************************************************"); - m_starter_message_showed = true; - } - - m_store_blockchain_interval.do_call(boost::bind(&blockchain_storage::store_blockchain, &m_blockchain_storage)); - m_miner.on_idle(); - return true; - } - //----------------------------------------------------------------------------------------------- -} diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h deleted file mode 100644 index c298451..0000000 --- a/src/cryptonote_core/cryptonote_core.h +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once - -#include -#include - -#include "p2p/net_node_common.h" -#include "cryptonote_protocol/cryptonote_protocol_handler_common.h" -#include "storages/portable_storage_template_helper.h" -#include "tx_pool.h" -#include "blockchain_storage.h" -#include "miner.h" -#include "connection_context.h" -#include "cryptonote_core/cryptonote_stat_info.h" -#include "warnings.h" -#include "crypto/hash.h" - -PUSH_WARNINGS -DISABLE_VS_WARNINGS(4355) - -namespace cryptonote -{ - /************************************************************************/ - /* */ - /************************************************************************/ - class core: public i_miner_handler - { - public: - core(i_cryptonote_protocol* pprotocol); - bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote_connection_context& context); - bool on_idle(); - bool handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block); - bool handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate = true); - i_cryptonote_protocol* get_protocol(){return m_pprotocol;} - - //-------------------- i_miner_handler ----------------------- - virtual bool handle_block_found( block& b); - virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, const blobdata& ex_nonce); - - - miner& get_miner(){return m_miner;} - static void init_options(boost::program_options::options_description& desc); - bool init(const boost::program_options::variables_map& vm); - bool set_genesis_block(const block& b); - bool deinit(); - uint64_t get_current_blockchain_height(); - bool get_blockchain_top(uint64_t& heeight, crypto::hash& top_id); - bool get_blocks(uint64_t start_offset, size_t count, std::list& blocks, std::list& txs); - bool get_blocks(uint64_t start_offset, size_t count, std::list& blocks); - template - bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) - { - return m_blockchain_storage.get_blocks(block_ids, blocks, missed_bs); - } - crypto::hash get_block_id_by_height(uint64_t height); - bool get_transactions(const std::vector& txs_ids, std::list& txs, std::list& missed_txs); - bool get_transaction(const crypto::hash &h, transaction &tx); - bool get_block_by_hash(const crypto::hash &h, block &blk); - void get_all_known_block_ids(std::list &main, std::list &alt, std::list &invalid); - - bool get_alternative_blocks(std::list& blocks); - size_t get_alternative_blocks_count(); - - void set_cryptonote_protocol(i_cryptonote_protocol* pprotocol); - void set_checkpoints(checkpoints&& chk_pts); - - bool get_pool_transactions(std::list& txs); - size_t get_pool_transactions_count(); - size_t get_blockchain_total_transactions(); - bool get_outs(uint64_t amount, std::list& pkeys); - bool have_block(const crypto::hash& id); - bool get_short_chain_history(std::list& ids); - bool find_blockchain_supplement(const std::list& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp); - bool find_blockchain_supplement(const std::list& qblock_ids, std::list > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count); - bool get_stat_info(core_stat_info& st_inf); - bool get_backward_blocks_sizes(uint64_t from_height, std::vector& sizes, size_t count); - bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector& indexs); - crypto::hash get_tail_id(); - 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); - void pause_mine(); - void resume_mine(); - blockchain_storage& get_blockchain_storage(){return m_blockchain_storage;} - //debug functions - void print_blockchain(uint64_t start_index, uint64_t end_index); - void print_blockchain_index(); - std::string print_pool(bool short_format); - void print_blockchain_outs(const std::string& file); - void on_synchronized(); - - private: - bool add_new_tx(const transaction& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prefix_hash, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block); - bool add_new_tx(const transaction& tx, tx_verification_context& tvc, bool keeped_by_block); - bool add_new_block(const block& b, block_verification_context& bvc); - bool load_state_data(); - bool parse_tx_from_blob(transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash, const blobdata& blob); - - bool check_tx_syntax(const transaction& tx); - //check correct values, amounts and all lightweight checks not related with database - bool check_tx_semantic(const transaction& tx, bool keeped_by_block); - //check if tx already in memory pool or in main blockchain - - bool is_key_image_spent(const crypto::key_image& key_im); - - bool check_tx_ring_signature(const txin_to_key& tx, const crypto::hash& tx_prefix_hash, const std::vector& sig); - bool is_tx_spendtime_unlocked(uint64_t unlock_time); - bool update_miner_block_template(); - bool handle_command_line(const boost::program_options::variables_map& vm); - bool on_update_blocktemplate_interval(); - bool check_tx_inputs_keyimages_diff(const transaction& tx); - - - tx_memory_pool m_mempool; - blockchain_storage m_blockchain_storage; - i_cryptonote_protocol* m_pprotocol; - critical_section m_incoming_tx_lock; - //m_miner and m_miner_addres are probably temporary here - miner m_miner; - account_public_address m_miner_address; - std::string m_config_folder; - cryptonote_protocol_stub m_protocol_stub; - math_helper::once_a_time_seconds<60*60*12, false> m_store_blockchain_interval; - friend class tx_validate_inputs; - std::atomic m_starter_message_showed; - }; -} - -POP_WARNINGS diff --git a/src/cryptonote_core/cryptonote_stat_info.h b/src/cryptonote_core/cryptonote_stat_info.h deleted file mode 100644 index 9d40674..0000000 --- a/src/cryptonote_core/cryptonote_stat_info.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once -#include "serialization/keyvalue_serialization.h" - - -namespace cryptonote -{ - struct core_stat_info - { - uint64_t tx_pool_size; - uint64_t blockchain_height; - uint64_t mining_speed; - uint64_t alternative_blocks; - std::string top_block_id_str; - - BEGIN_KV_SERIALIZE_MAP() - KV_SERIALIZE(tx_pool_size) - KV_SERIALIZE(blockchain_height) - KV_SERIALIZE(mining_speed) - KV_SERIALIZE(alternative_blocks) - KV_SERIALIZE(top_block_id_str) - END_KV_SERIALIZE_MAP() - }; -} diff --git a/src/cryptonote_core/difficulty.cpp b/src/cryptonote_core/difficulty.cpp deleted file mode 100644 index 3dde6ad..0000000 --- a/src/cryptonote_core/difficulty.cpp +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include -#include -#include - -#include "common/int-util.h" -#include "crypto/hash.h" -#include "cryptonote_config.h" -#include "difficulty.h" - -namespace cryptonote { - - using std::size_t; - using std::uint64_t; - using std::vector; - -#if defined(_MSC_VER) -#include -#include - - static inline void mul(uint64_t a, uint64_t b, uint64_t &low, uint64_t &high) { - low = mul128(a, b, &high); - } - -#else - - static inline void mul(uint64_t a, uint64_t b, uint64_t &low, uint64_t &high) { - typedef unsigned __int128 uint128_t; - uint128_t res = (uint128_t) a * (uint128_t) b; - low = (uint64_t) res; - high = (uint64_t) (res >> 64); - } - -#endif - - static inline bool cadd(uint64_t a, uint64_t b) { - return a + b < a; - } - - static inline bool cadc(uint64_t a, uint64_t b, bool c) { - return a + b < a || (c && a + b == (uint64_t) -1); - } - - bool check_hash(const crypto::hash &hash, difficulty_type difficulty) { - uint64_t low, high, top, cur; - // First check the highest word, this will most likely fail for a random hash. - mul(swap64le(((const uint64_t *) &hash)[3]), difficulty, top, high); - if (high != 0) { - return false; - } - mul(swap64le(((const uint64_t *) &hash)[0]), difficulty, low, cur); - mul(swap64le(((const uint64_t *) &hash)[1]), difficulty, low, high); - bool carry = cadd(cur, low); - cur = high; - mul(swap64le(((const uint64_t *) &hash)[2]), difficulty, low, high); - carry = cadc(cur, low, carry); - carry = cadc(high, top, carry); - return !carry; - } - - difficulty_type next_difficulty(vector timestamps, vector cumulative_difficulties, size_t target_seconds) { - //cutoff DIFFICULTY_LAG - if(timestamps.size() > DIFFICULTY_WINDOW) - { - timestamps.resize(DIFFICULTY_WINDOW); - cumulative_difficulties.resize(DIFFICULTY_WINDOW); - } - - - size_t length = timestamps.size(); - assert(length == cumulative_difficulties.size()); - if (length <= 1) { - return 1; - } - static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small"); - assert(length <= DIFFICULTY_WINDOW); - sort(timestamps.begin(), timestamps.end()); - size_t cut_begin, cut_end; - static_assert(2 * DIFFICULTY_CUT <= DIFFICULTY_WINDOW - 2, "Cut length is too large"); - if (length <= DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) { - cut_begin = 0; - cut_end = length; - } else { - cut_begin = (length - (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT) + 1) / 2; - cut_end = cut_begin + (DIFFICULTY_WINDOW - 2 * DIFFICULTY_CUT); - } - assert(/*cut_begin >= 0 &&*/ cut_begin + 2 <= cut_end && cut_end <= length); - uint64_t time_span = timestamps[cut_end - 1] - timestamps[cut_begin]; - if (time_span == 0) { - time_span = 1; - } - difficulty_type total_work = cumulative_difficulties[cut_end - 1] - cumulative_difficulties[cut_begin]; - assert(total_work > 0); - uint64_t low, high; - mul(total_work, target_seconds, low, high); - if (high != 0 || low + time_span - 1 < low) { - return 0; - } - return (low + time_span - 1) / time_span; - } - - difficulty_type next_difficulty(vector timestamps, vector cumulative_difficulties) - { - return next_difficulty(std::move(timestamps), std::move(cumulative_difficulties), DIFFICULTY_TARGET); - } -} diff --git a/src/cryptonote_core/miner.cpp b/src/cryptonote_core/miner.cpp deleted file mode 100644 index 56b459d..0000000 --- a/src/cryptonote_core/miner.cpp +++ /dev/null @@ -1,365 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#include -#include -#include -#include -#include -#include -#include "misc_language.h" -#include "include_base_utils.h" -#include "cryptonote_basic_impl.h" -#include "cryptonote_format_utils.h" -#include "file_io_utils.h" -#include "common/command_line.h" -#include "string_coding.h" -#include "storages/portable_storage_template_helper.h" - -using namespace epee; - -#include "miner.h" - - - -namespace cryptonote -{ - - namespace - { - const command_line::arg_descriptor arg_extra_messages = {"extra-messages-file", "Specify file for extra messages to include into coinbase transactions", "", true}; - const command_line::arg_descriptor arg_start_mining = {"start-mining", "Specify wallet address to mining for", "", true}; - const command_line::arg_descriptor arg_mining_threads = {"mining-threads", "Specify mining threads count", 0, true}; - } - - - miner::miner(i_miner_handler* phandler):m_stop(1), - m_template(boost::value_initialized()), - m_template_no(0), - m_diffic(0), - m_thread_index(0), - m_phandler(phandler), - m_height(0), - m_pausers_count(0), - m_threads_total(0), - m_starter_nonce(0), - m_last_hr_merge_time(0), - m_hashes(0), - m_do_print_hashrate(false), - m_do_mining(false), - m_current_hash_rate(0) - { - - } - //----------------------------------------------------------------------------------------------------- - miner::~miner() - { - stop(); - } - //----------------------------------------------------------------------------------------------------- - bool miner::set_block_template(const block& bl, const difficulty_type& di, uint64_t height) - { - CRITICAL_REGION_LOCAL(m_template_lock); - m_template = bl; - m_diffic = di; - m_height = height; - ++m_template_no; - m_starter_nonce = crypto::rand(); - return true; - } - //----------------------------------------------------------------------------------------------------- - bool miner::on_block_chain_update() - { - if(!is_mining()) - return true; - - return request_block_template(); - } - //----------------------------------------------------------------------------------------------------- - bool miner::request_block_template() - { - block bl = AUTO_VAL_INIT(bl); - difficulty_type di = AUTO_VAL_INIT(di); - uint64_t height = AUTO_VAL_INIT(height); - cryptonote::blobdata extra_nonce; - if(m_extra_messages.size() && m_config.current_extra_message_index < m_extra_messages.size()) - { - extra_nonce = m_extra_messages[m_config.current_extra_message_index]; - } - - if(!m_phandler->get_block_template(bl, m_mine_address, di, height, extra_nonce)) - { - LOG_ERROR("Failed to get_block_template(), stopping mining"); - return false; - } - set_block_template(bl, di, height); - return true; - } - //----------------------------------------------------------------------------------------------------- - bool miner::on_idle() - { - m_update_block_template_interval.do_call([&](){ - if(is_mining())request_block_template(); - return true; - }); - - m_update_merge_hr_interval.do_call([&](){ - merge_hr(); - return true; - }); - - return true; - } - //----------------------------------------------------------------------------------------------------- - void miner::do_print_hashrate(bool do_hr) - { - m_do_print_hashrate = do_hr; - } - //----------------------------------------------------------------------------------------------------- - void miner::merge_hr() - { - if(m_last_hr_merge_time && is_mining()) - { - m_current_hash_rate = m_hashes * 1000 / ((misc_utils::get_tick_count() - m_last_hr_merge_time + 1)); - CRITICAL_REGION_LOCAL(m_last_hash_rates_lock); - m_last_hash_rates.push_back(m_current_hash_rate); - if(m_last_hash_rates.size() > 19) - m_last_hash_rates.pop_front(); - if(m_do_print_hashrate) - { - uint64_t total_hr = std::accumulate(m_last_hash_rates.begin(), m_last_hash_rates.end(), 0); - float hr = static_cast(total_hr)/static_cast(m_last_hash_rates.size()); - std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << ENDL; - } - } - m_last_hr_merge_time = misc_utils::get_tick_count(); - m_hashes = 0; - } - //----------------------------------------------------------------------------------------------------- - void miner::init_options(boost::program_options::options_description& desc) - { - command_line::add_arg(desc, arg_extra_messages); - command_line::add_arg(desc, arg_start_mining); - command_line::add_arg(desc, arg_mining_threads); - } - //----------------------------------------------------------------------------------------------------- - bool miner::init(const boost::program_options::variables_map& vm) - { - if(command_line::has_arg(vm, arg_extra_messages)) - { - std::string buff; - bool r = file_io_utils::load_file_to_string(command_line::get_arg(vm, arg_extra_messages), buff); - CHECK_AND_ASSERT_MES(r, false, "Failed to load file with extra messages: " << command_line::get_arg(vm, arg_extra_messages)); - std::vector extra_vec; - boost::split(extra_vec, buff, boost::is_any_of("\n"), boost::token_compress_on ); - m_extra_messages.resize(extra_vec.size()); - for(size_t i = 0; i != extra_vec.size(); i++) - { - string_tools::trim(extra_vec[i]); - if(!extra_vec[i].size()) - continue; - std::string buff = string_encoding::base64_decode(extra_vec[i]); - if(buff != "0") - m_extra_messages[i] = buff; - } - m_config_folder_path = boost::filesystem::path(command_line::get_arg(vm, arg_extra_messages)).parent_path().string(); - m_config = AUTO_VAL_INIT(m_config); - epee::serialization::load_t_from_json_file(m_config, m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME); - LOG_PRINT_L0("Loaded " << m_extra_messages.size() << " extra messages, current index " << m_config.current_extra_message_index); - } - - if(command_line::has_arg(vm, arg_start_mining)) - { - if(!cryptonote::get_account_address_from_str(m_mine_address, command_line::get_arg(vm, arg_start_mining))) - { - LOG_ERROR("Target account address " << command_line::get_arg(vm, arg_start_mining) << " has wrong format, starting daemon canceled"); - return false; - } - m_threads_total = 1; - m_do_mining = true; - if(command_line::has_arg(vm, arg_mining_threads)) - { - m_threads_total = command_line::get_arg(vm, arg_mining_threads); - } - } - - return true; - } - //----------------------------------------------------------------------------------------------------- - bool miner::is_mining() - { - return !m_stop; - } - //----------------------------------------------------------------------------------------------------- - bool miner::start(const account_public_address& adr, size_t threads_count, const boost::thread::attributes& attrs) - { - m_mine_address = adr; - m_threads_total = static_cast(threads_count); - m_starter_nonce = crypto::rand(); - CRITICAL_REGION_LOCAL(m_threads_lock); - if(is_mining()) - { - LOG_ERROR("Starting miner but it's already started"); - return false; - } - - if(!m_threads.empty()) - { - LOG_ERROR("Unable to start miner because there are active mining threads"); - return false; - } - - if(!m_template_no) - request_block_template();//lets update block template - - boost::interprocess::ipcdetail::atomic_write32(&m_stop, 0); - boost::interprocess::ipcdetail::atomic_write32(&m_thread_index, 0); - - for(size_t i = 0; i != threads_count; i++) - { - m_threads.push_back(boost::thread(attrs, boost::bind(&miner::worker_thread, this))); - } - - LOG_PRINT_L0("Mining has started with " << threads_count << " threads, good luck!" ) - return true; - } - //----------------------------------------------------------------------------------------------------- - uint64_t miner::get_speed() - { - if(is_mining()) - return m_current_hash_rate; - else - return 0; - } - //----------------------------------------------------------------------------------------------------- - void miner::send_stop_signal() - { - boost::interprocess::ipcdetail::atomic_write32(&m_stop, 1); - } - //----------------------------------------------------------------------------------------------------- - bool miner::stop() - { - send_stop_signal(); - CRITICAL_REGION_LOCAL(m_threads_lock); - - BOOST_FOREACH(boost::thread& th, m_threads) - th.join(); - - m_threads.clear(); - LOG_PRINT_L0("Mining has been stopped, " << m_threads.size() << " finished" ); - return true; - } - //----------------------------------------------------------------------------------------------------- - bool miner::find_nonce_for_given_block(block& bl, const difficulty_type& diffic, uint64_t height) - { - for(; bl.nonce != std::numeric_limits::max(); bl.nonce++) - { - crypto::hash h; - get_block_longhash(bl, h, height); - - if(check_hash(h, diffic)) - { - return true; - } - } - return false; - } - //----------------------------------------------------------------------------------------------------- - void miner::on_synchronized() - { - if(m_do_mining) - { - boost::thread::attributes attrs; - attrs.set_stack_size(THREAD_STACK_SIZE); - - start(m_mine_address, m_threads_total, attrs); - } - } - //----------------------------------------------------------------------------------------------------- - void miner::pause() - { - CRITICAL_REGION_LOCAL(m_miners_count_lock); - ++m_pausers_count; - if(m_pausers_count == 1 && is_mining()) - LOG_PRINT_L2("MINING PAUSED"); - } - //----------------------------------------------------------------------------------------------------- - void miner::resume() - { - CRITICAL_REGION_LOCAL(m_miners_count_lock); - --m_pausers_count; - if(m_pausers_count < 0) - { - m_pausers_count = 0; - LOG_PRINT_RED_L0("Unexpected miner::resume() called"); - } - if(!m_pausers_count && is_mining()) - LOG_PRINT_L2("MINING RESUMED"); - } - //----------------------------------------------------------------------------------------------------- - bool miner::worker_thread() - { - uint32_t th_local_index = boost::interprocess::ipcdetail::atomic_inc32(&m_thread_index); - LOG_PRINT_L0("Miner thread was started ["<< th_local_index << "]"); - log_space::log_singletone::set_thread_log_prefix(std::string("[miner ") + std::to_string(th_local_index) + "]"); - uint32_t nonce = m_starter_nonce + th_local_index; - uint64_t height = 0; - difficulty_type local_diff = 0; - uint32_t local_template_ver = 0; - block b; - while(!m_stop) - { - if(m_pausers_count)//anti split workaround - { - misc_utils::sleep_no_w(100); - continue; - } - - if(local_template_ver != m_template_no) - { - - CRITICAL_REGION_BEGIN(m_template_lock); - b = m_template; - local_diff = m_diffic; - height = m_height; - CRITICAL_REGION_END(); - local_template_ver = m_template_no; - nonce = m_starter_nonce + th_local_index; - } - - if(!local_template_ver)//no any set_block_template call - { - LOG_PRINT_L2("Block template not set yet"); - epee::misc_utils::sleep_no_w(1000); - continue; - } - - b.nonce = nonce; - crypto::hash h; - get_block_longhash(b, h, height); - - if(check_hash(h, local_diff)) - { - //we lucky! - ++m_config.current_extra_message_index; - LOG_PRINT_GREEN("Found block for difficulty: " << local_diff, LOG_LEVEL_0); - if(!m_phandler->handle_block_found(b)) - { - --m_config.current_extra_message_index; - }else - { - //success update, lets update config - epee::serialization::store_t_to_json_file(m_config, m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME); - } - } - nonce+=m_threads_total; - ++m_hashes; - } - LOG_PRINT_L0("Miner thread stopped ["<< th_local_index << "]"); - return true; - } - //----------------------------------------------------------------------------------------------------- -} - diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp deleted file mode 100644 index 24e5752..0000000 --- a/src/cryptonote_core/tx_pool.cpp +++ /dev/null @@ -1,409 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include -#include -#include -#include - -#include "tx_pool.h" -#include "cryptonote_format_utils.h" -#include "cryptonote_boost_serialization.h" -#include "cryptonote_config.h" -#include "blockchain_storage.h" -#include "common/boost_serialization_helper.h" -#include "common/int-util.h" -#include "misc_language.h" -#include "warnings.h" -#include "crypto/hash.h" - -DISABLE_VS_WARNINGS(4244 4345 4503) //'boost::foreach_detail_::or_' : decorated name length exceeded, name was truncated - -namespace cryptonote -{ - //--------------------------------------------------------------------------------- - tx_memory_pool::tx_memory_pool(blockchain_storage& bchs): m_blockchain(bchs) - { - - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::add_tx(const transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool kept_by_block) - { - - - if(!check_inputs_types_supported(tx)) - { - tvc.m_verifivation_failed = true; - return false; - } - - uint64_t inputs_amount = 0; - if(!get_inputs_money_amount(tx, inputs_amount)) - { - tvc.m_verifivation_failed = true; - return false; - } - - uint64_t outputs_amount = get_outs_money_amount(tx); - - if(outputs_amount >= inputs_amount) - { - LOG_PRINT_L0("transaction use more money then it has: use " << outputs_amount << ", have " << inputs_amount); - tvc.m_verifivation_failed = true; - return false; - } - - //check key images for transaction if it is not kept by block - if(!kept_by_block) - { - if(have_tx_keyimges_as_spent(tx)) - { - LOG_ERROR("Transaction with id= "<< id << " used already spent key images"); - tvc.m_verifivation_failed = true; - return false; - } - } - - - crypto::hash max_used_block_id = null_hash; - uint64_t max_used_block_height = 0; - bool ch_inp_res = m_blockchain.check_tx_inputs(tx, max_used_block_height, max_used_block_id); - CRITICAL_REGION_LOCAL(m_transactions_lock); - if(!ch_inp_res) - { - if(kept_by_block) - { - //anyway add this transaction to pool, because it related to block - auto txd_p = m_transactions.insert(transactions_container::value_type(id, tx_details())); - CHECK_AND_ASSERT_MES(txd_p.second, false, "transaction already exists at inserting in memory pool"); - txd_p.first->second.blob_size = blob_size; - txd_p.first->second.tx = tx; - txd_p.first->second.fee = inputs_amount - outputs_amount; - txd_p.first->second.max_used_block_id = null_hash; - txd_p.first->second.max_used_block_height = 0; - txd_p.first->second.kept_by_block = kept_by_block; - tvc.m_verifivation_impossible = true; - tvc.m_added_to_pool = true; - }else - { - LOG_PRINT_L0("tx used wrong inputs, rejected"); - tvc.m_verifivation_failed = true; - return false; - } - }else - { - //update transactions container - auto txd_p = m_transactions.insert(transactions_container::value_type(id, tx_details())); - CHECK_AND_ASSERT_MES(txd_p.second, false, "intrnal error: transaction already exists at inserting in memorypool"); - txd_p.first->second.blob_size = blob_size; - txd_p.first->second.tx = tx; - txd_p.first->second.kept_by_block = kept_by_block; - txd_p.first->second.fee = inputs_amount - outputs_amount; - txd_p.first->second.max_used_block_id = max_used_block_id; - txd_p.first->second.max_used_block_height = max_used_block_height; - txd_p.first->second.last_failed_height = 0; - txd_p.first->second.last_failed_id = null_hash; - tvc.m_added_to_pool = true; - - if(txd_p.first->second.fee > 0) - tvc.m_should_be_relayed = true; - } - - tvc.m_verifivation_failed = true; - //update image_keys container, here should everything goes ok. - BOOST_FOREACH(const auto& in, tx.vin) - { - CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, txin, false); - std::unordered_set& kei_image_set = m_spent_key_images[txin.k_image]; - CHECK_AND_ASSERT_MES(kept_by_block || kei_image_set.size() == 0, false, "internal error: keeped_by_block=" << kept_by_block - << ", kei_image_set.size()=" << kei_image_set.size() << ENDL << "txin.k_image=" << txin.k_image << ENDL - << "tx_id=" << id ); - auto ins_res = kei_image_set.insert(id); - CHECK_AND_ASSERT_MES(ins_res.second, false, "internal error: try to insert duplicate iterator in key_image set"); - } - - tvc.m_verifivation_failed = false; - //succeed - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::add_tx(const transaction &tx, tx_verification_context& tvc, bool keeped_by_block) - { - crypto::hash h = null_hash; - size_t blob_size = 0; - get_transaction_hash(tx, h, blob_size); - return add_tx(tx, h, blob_size, tvc, keeped_by_block); - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::remove_transaction_keyimages(const transaction& tx) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - BOOST_FOREACH(const txin_v& vi, tx.vin) - { - CHECKED_GET_SPECIFIC_VARIANT(vi, const txin_to_key, txin, false); - auto it = m_spent_key_images.find(txin.k_image); - CHECK_AND_ASSERT_MES(it != m_spent_key_images.end(), false, "failed to find transaction input in key images. img=" << txin.k_image << ENDL - << "transaction id = " << get_transaction_hash(tx)); - std::unordered_set& key_image_set = it->second; - CHECK_AND_ASSERT_MES(key_image_set.size(), false, "empty key_image set, img=" << txin.k_image << ENDL - << "transaction id = " << get_transaction_hash(tx)); - - auto it_in_set = key_image_set.find(get_transaction_hash(tx)); - CHECK_AND_ASSERT_MES(key_image_set.size(), false, "transaction id not found in key_image set, img=" << txin.k_image << ENDL - << "transaction id = " << get_transaction_hash(tx)); - key_image_set.erase(it_in_set); - if(!key_image_set.size()) - { - //it is now empty hash container for this key_image - m_spent_key_images.erase(it); - } - - } - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::take_tx(const crypto::hash &id, transaction &tx, size_t& blob_size, uint64_t& fee) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - auto it = m_transactions.find(id); - if(it == m_transactions.end()) - return false; - - tx = it->second.tx; - blob_size = it->second.blob_size; - fee = it->second.fee; - remove_transaction_keyimages(it->second.tx); - m_transactions.erase(it); - return true; - } - //--------------------------------------------------------------------------------- - size_t tx_memory_pool::get_transactions_count() - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - return m_transactions.size(); - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::get_transactions(std::list& txs) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - BOOST_FOREACH(const auto& tx_vt, m_transactions) - txs.push_back(tx_vt.second.tx); - - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::get_transaction(const crypto::hash& id, transaction& tx) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - auto it = m_transactions.find(id); - if(it == m_transactions.end()) - return false; - tx = it->second.tx; - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id) - { - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id) - { - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::have_tx(const crypto::hash &id) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - if(m_transactions.count(id)) - return true; - return false; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::have_tx_keyimges_as_spent(const transaction& tx) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - BOOST_FOREACH(const auto& in, tx.vin) - { - CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, true);//should never fail - if(have_tx_keyimg_as_spent(tokey_in.k_image)) - return true; - } - return false; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::have_tx_keyimg_as_spent(const crypto::key_image& key_im) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - return m_spent_key_images.end() != m_spent_key_images.find(key_im); - } - //--------------------------------------------------------------------------------- - void tx_memory_pool::lock() - { - m_transactions_lock.lock(); - } - //--------------------------------------------------------------------------------- - void tx_memory_pool::unlock() - { - m_transactions_lock.unlock(); - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::is_transaction_ready_to_go(tx_details& txd) - { - //not the best implementation at this time, sorry :( - //check is ring_signature already checked ? - if(txd.max_used_block_id == null_hash) - {//not checked, lets try to check - - if(txd.last_failed_id != null_hash && m_blockchain.get_current_blockchain_height() > txd.last_failed_height && txd.last_failed_id == m_blockchain.get_block_id_by_height(txd.last_failed_height)) - return false;//we already sure that this tx is broken for this height - - if(!m_blockchain.check_tx_inputs(txd.tx, txd.max_used_block_height, txd.max_used_block_id)) - { - txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1; - txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height); - return false; - } - }else - { - if(txd.max_used_block_height >= m_blockchain.get_current_blockchain_height()) - return false; - if(m_blockchain.get_block_id_by_height(txd.max_used_block_height) != txd.max_used_block_id) - { - //if we already failed on this height and id, skip actual ring signature check - if(txd.last_failed_id == m_blockchain.get_block_id_by_height(txd.last_failed_height)) - return false; - //check ring signature again, it is possible (with very small chance) that this transaction become again valid - if(!m_blockchain.check_tx_inputs(txd.tx, txd.max_used_block_height, txd.max_used_block_id)) - { - txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1; - txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height); - return false; - } - } - } - //if we here, transaction seems valid, but, anyway, check for key_images collisions with blockchain, just to be sure - if(m_blockchain.have_tx_keyimges_as_spent(txd.tx)) - return false; - - //transaction is ok. - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::have_key_images(const std::unordered_set& k_images, const transaction& tx) - { - for(size_t i = 0; i!= tx.vin.size(); i++) - { - CHECKED_GET_SPECIFIC_VARIANT(tx.vin[i], const txin_to_key, itk, false); - if(k_images.count(itk.k_image)) - return true; - } - return false; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::append_key_images(std::unordered_set& k_images, const transaction& tx) - { - for(size_t i = 0; i!= tx.vin.size(); i++) - { - CHECKED_GET_SPECIFIC_VARIANT(tx.vin[i], const txin_to_key, itk, false); - auto i_res = k_images.insert(itk.k_image); - CHECK_AND_ASSERT_MES(i_res.second, false, "internal error: key images pool cache - inserted duplicate image in set: " << itk.k_image); - } - return true; - } - //--------------------------------------------------------------------------------- - std::string tx_memory_pool::print_pool(bool short_format) - { - std::stringstream ss; - CRITICAL_REGION_LOCAL(m_transactions_lock); - BOOST_FOREACH(transactions_container::value_type& txe, m_transactions) - { - if(short_format) - { - tx_details& txd = txe.second; - ss << "id: " << txe.first << ENDL - << "blob_size: " << txd.blob_size << ENDL - << "fee: " << txd.fee << ENDL - << "kept_by_block: " << txd.kept_by_block << ENDL - << "max_used_block_height: " << txd.max_used_block_height << ENDL - << "max_used_block_id: " << txd.max_used_block_id << ENDL - << "last_failed_height: " << txd.last_failed_height << ENDL - << "last_failed_id: " << txd.last_failed_id << ENDL; - }else - { - tx_details& txd = txe.second; - ss << "id: " << txe.first << ENDL - << obj_to_json_str(txd.tx) << ENDL - << "blob_size: " << txd.blob_size << ENDL - << "fee: " << txd.fee << ENDL - << "kept_by_block: " << txd.kept_by_block << ENDL - << "max_used_block_height: " << txd.max_used_block_height << ENDL - << "max_used_block_id: " << txd.max_used_block_id << ENDL - << "last_failed_height: " << txd.last_failed_height << ENDL - << "last_failed_id: " << txd.last_failed_id << ENDL; - } - - } - return ss.str(); - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee) - { - CRITICAL_REGION_LOCAL(m_transactions_lock); - - total_size = 0; - fee = 0; - - size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; - std::unordered_set k_images; - BOOST_FOREACH(transactions_container::value_type& tx, m_transactions) - { - if (max_total_size < total_size + tx.second.blob_size) - continue; - - if (!is_transaction_ready_to_go(tx.second) || have_key_images(k_images, tx.second.tx)) - continue; - - bl.tx_hashes.push_back(tx.first); - total_size += tx.second.blob_size; - fee += tx.second.fee; - append_key_images(k_images, tx.second.tx); - } - - return true; - } - //--------------------------------------------------------------------------------- - bool tx_memory_pool::init(const std::string& config_folder) - { - m_config_folder = config_folder; - std::string state_file_path = config_folder + "/" + CRYPTONOTE_POOLDATA_FILENAME; - boost::system::error_code ec; - if(!boost::filesystem::exists(state_file_path, ec)) - return true; - bool res = tools::unserialize_obj_from_file(*this, state_file_path); - if(!res) - { - LOG_PRINT_L0("Failed to load memory pool from file " << state_file_path); - } - return res; - } - - //--------------------------------------------------------------------------------- - bool tx_memory_pool::deinit() - { - if (!tools::create_directories_if_necessary(m_config_folder)) - { - LOG_PRINT_L0("Failed to create data directory: " << m_config_folder); - return false; - } - - std::string state_file_path = m_config_folder + "/" + CRYPTONOTE_POOLDATA_FILENAME; - bool res = tools::serialize_obj_to_file(*this, state_file_path); - if(!res) - { - LOG_PRINT_L0("Failed to serialize memory pool to file " << state_file_path); - } - return true; - } -} diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h deleted file mode 100644 index 3978dfb..0000000 --- a/src/cryptonote_core/tx_pool.h +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#pragma once -#include "include_base_utils.h" -using namespace epee; - - -#include -#include -#include -#include -#include - -#include "string_tools.h" -#include "syncobj.h" -#include "cryptonote_basic_impl.h" -#include "verification_context.h" -#include "crypto/hash.h" - - -namespace cryptonote -{ - class blockchain_storage; - /************************************************************************/ - /* */ - /************************************************************************/ - - class tx_memory_pool: boost::noncopyable - { - public: - tx_memory_pool(blockchain_storage& bchs); - bool add_tx(const transaction &tx, const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool keeped_by_block); - bool add_tx(const transaction &tx, tx_verification_context& tvc, bool keeped_by_block); - //gets tx and remove it from pool - bool take_tx(const crypto::hash &id, transaction &tx, size_t& blob_size, uint64_t& fee); - - bool have_tx(const crypto::hash &id); - bool have_tx_keyimg_as_spent(const crypto::key_image& key_im); - bool have_tx_keyimges_as_spent(const transaction& tx); - - bool on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id); - bool on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id); - - void lock(); - void unlock(); - - // load/store operations - bool init(const std::string& config_folder); - bool deinit(); - bool fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee); - bool get_transactions(std::list& txs); - bool get_transaction(const crypto::hash& h, transaction& tx); - size_t get_transactions_count(); - bool remove_transaction_keyimages(const transaction& tx); - bool have_key_images(const std::unordered_set& kic, const transaction& tx); - bool append_key_images(std::unordered_set& kic, const transaction& tx); - std::string print_pool(bool short_format); - - /*bool flush_pool(const std::strig& folder); - bool inflate_pool(const std::strig& folder);*/ - -#define CURRENT_MEMPOOL_ARCHIVE_VER 7 - - template - void serialize(archive_t & a, const unsigned int version) - { - if(version < CURRENT_MEMPOOL_ARCHIVE_VER ) - return; - CRITICAL_REGION_LOCAL(m_transactions_lock); - a & m_transactions; - a & m_spent_key_images; - } - - struct tx_details - { - transaction tx; - size_t blob_size; - uint64_t fee; - crypto::hash max_used_block_id; - uint64_t max_used_block_height; - bool kept_by_block; - // - uint64_t last_failed_height; - crypto::hash last_failed_id; - }; - - private: - bool is_transaction_ready_to_go(tx_details& txd); - typedef std::unordered_map transactions_container; - typedef std::unordered_map > key_images_container; - - epee::critical_section m_transactions_lock; - transactions_container m_transactions; - key_images_container m_spent_key_images; - - //transactions_container m_alternative_transactions; - - std::string m_config_folder; - blockchain_storage& m_blockchain; - /************************************************************************/ - /* */ - /************************************************************************/ - /*class inputs_visitor: public boost::static_visitor - { - key_images_container& m_spent_keys; - public: - inputs_visitor(key_images_container& spent_keys): m_spent_keys(spent_keys) - {} - bool operator()(const txin_to_key& tx) const - { - auto pr = m_spent_keys.insert(tx.k_image); - CHECK_AND_ASSERT_MES(pr.second, false, "Tried to insert transaction with input seems already spent, input: " << epee::string_tools::pod_to_hex(tx.k_image)); - return true; - } - bool operator()(const txin_gen& tx) const - { - CHECK_AND_ASSERT_MES(false, false, "coinbase transaction in memory pool"); - return false; - } - bool operator()(const txin_to_script& tx) const {return false;} - bool operator()(const txin_to_scripthash& tx) const {return false;} - }; */ - /************************************************************************/ - /* */ - /************************************************************************/ - class amount_visitor: public boost::static_visitor - { - public: - uint64_t operator()(const txin_to_key& tx) const - { - return tx.amount; - } - uint64_t operator()(const txin_gen& tx) const - { - CHECK_AND_ASSERT_MES(false, false, "coinbase transaction in memory pool"); - return 0; - } - uint64_t operator()(const txin_to_script& tx) const {return 0;} - uint64_t operator()(const txin_to_scripthash& tx) const {return 0;} - }; - -#if defined(DEBUG_CREATE_BLOCK_TEMPLATE) - friend class blockchain_storage; -#endif - }; -} - -namespace boost -{ - namespace serialization - { - template - void serialize(archive_t & ar, cryptonote::tx_memory_pool::tx_details& td, const unsigned int version) - { - ar & td.blob_size; - ar & td.fee; - ar & td.tx; - ar & td.max_used_block_height; - ar & td.max_used_block_id; - ar & td.last_failed_height; - ar & td.last_failed_id; - - } - } -} -BOOST_CLASS_VERSION(cryptonote::tx_memory_pool, CURRENT_MEMPOOL_ARCHIVE_VER) - - - diff --git a/src/cryptonote_core/verification_context.h b/src/cryptonote_core/verification_context.h deleted file mode 100644 index 210cc2d..0000000 --- a/src/cryptonote_core/verification_context.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2012-2013 The Cryptonote developers -// Distributed under the MIT/X11 software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - - -#pragma once -namespace cryptonote -{ - /************************************************************************/ - /* */ - /************************************************************************/ - struct tx_verification_context - { - bool m_should_be_relayed; - bool m_verifivation_failed; //bad tx, should drop connection - bool m_verifivation_impossible; //the transaction is related with an alternative blockchain - bool m_added_to_pool; - }; - - struct block_verification_context - { - bool m_added_to_main_chain; - bool m_verifivation_failed; //bad block, should drop connection - bool m_marked_as_orphaned; - bool m_already_exists; - }; -} diff --git a/src/main.cc b/src/main.cc index 460177b..e4d11cc 100644 --- a/src/main.cc +++ b/src/main.cc @@ -7,11 +7,8 @@ #include #include "cryptonote_core/cryptonote_basic.h" #include "cryptonote_core/cryptonote_format_utils.h" -//#include "cryptonote_protocol/blobdatatype.h" -//#include "crypto/crypto.h" -//#include "crypto/hash.h" #include "common/base58.h" -#include "serialization/binary_utils.h" +//#include "serialization/binary_utils.h" #include #define THROW_ERROR_EXCEPTION(x) Nan::ThrowError(x)