diff options
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r-- | src/cryptonote_core/account.cpp | 8 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 24 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 22 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 8 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_format_utils.h | 33 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.cpp | 47 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.h | 3 |
7 files changed, 91 insertions, 54 deletions
diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp index 89ad4184c..bd703eee2 100644 --- a/src/cryptonote_core/account.cpp +++ b/src/cryptonote_core/account.cpp @@ -72,7 +72,7 @@ DISABLE_VS_WARNINGS(4244 4345) generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key, second, two_random ? false : true); - struct tm timestamp; + struct tm timestamp = {0}; timestamp.tm_year = 2014 - 1900; // year 2014 timestamp.tm_mon = 6 - 1; // month june timestamp.tm_mday = 8; // 8th of june @@ -83,6 +83,8 @@ DISABLE_VS_WARNINGS(4244 4345) if (recover) { m_creation_timestamp = mktime(×tamp); + if (m_creation_timestamp == (uint64_t)-1) // failure + m_creation_timestamp = 0; // lowest value } else { @@ -97,7 +99,7 @@ DISABLE_VS_WARNINGS(4244 4345) m_keys.m_spend_secret_key = spendkey; m_keys.m_view_secret_key = viewkey; - struct tm timestamp; + struct tm timestamp = {0}; timestamp.tm_year = 2014 - 1900; // year 2014 timestamp.tm_mon = 4 - 1; // month april timestamp.tm_mday = 15; // 15th of april @@ -106,6 +108,8 @@ DISABLE_VS_WARNINGS(4244 4345) timestamp.tm_sec = 0; m_creation_timestamp = mktime(×tamp); + if (m_creation_timestamp == (uint64_t)-1) // failure + m_creation_timestamp = 0; // lowest value } //----------------------------------------------------------------- void account_base::create_from_viewkey(const cryptonote::account_public_address& address, const crypto::secret_key& viewkey) diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index c368d7b24..f0779dad0 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -525,6 +525,7 @@ bool Blockchain::reset_and_set_genesis_block(const block& b) { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); + m_timestamps_and_difficulties_height = 0; m_alternative_chains.clear(); m_db->reset(); m_hardfork->init(); @@ -1084,7 +1085,7 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m size_t txs_size; uint64_t fee; - if (!m_tx_pool.fill_block_template(b, median_size, already_generated_coins, txs_size, fee)) + if (!m_tx_pool.fill_block_template(b, median_size, already_generated_coins, txs_size, fee, m_hardfork->get_current_version())) { return false; } @@ -1777,7 +1778,7 @@ bool Blockchain::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMA tx_out_index toi = m_db->get_output_tx_and_index(i.amount, i.index); bool unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first)); - res.outs.push_back({od.pubkey, od.commitment, unlocked}); + res.outs.push_back({od.pubkey, od.commitment, unlocked, od.height, toi.first}); } return true; } @@ -1895,11 +1896,11 @@ bool Blockchain::get_transactions(const t_ids_container& txs_ids, t_tx_container { try { - txs.push_back(m_db->get_tx(tx_hash)); - } - catch (const TX_DNE& e) - { - missed_txs.push_back(tx_hash); + transaction tx; + if (m_db->get_tx(tx_hash, tx)) + txs.push_back(std::move(tx)); + else + missed_txs.push_back(tx_hash); } catch (const std::exception& e) { @@ -2187,7 +2188,10 @@ bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_heigh max_used_block_height = 0; TIME_MEASURE_FINISH(a); if(m_show_time_stats) - LOG_PRINT_L0("HASH: " << "-" << " VIN/VOUT: " << tx.vin.size() << "/" << tx.vout.size() << " H: " << 0 << " chcktx: " << a); + { + size_t mixin = tx.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(tx.vin[0]).key_offsets.size() - 1 : 0; + LOG_PRINT_L0("HASH: " << "-" << " I/M/O: " << tx.vin.size() << "/" << mixin << "/" << tx.vout.size() << " H: " << 0 << " chcktx: " << a); + } return true; } #endif @@ -2197,8 +2201,8 @@ bool Blockchain::check_tx_inputs(transaction& tx, uint64_t& max_used_block_heigh TIME_MEASURE_FINISH(a); if(m_show_time_stats) { - size_t mix = tx.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(tx.vin[0]).key_offsets.size() : 0; - LOG_PRINT_L0("HASH: " << get_transaction_hash(tx) << " VIN/MIX/VOUT: " << tx.vin.size() << "/" << mix << "/" << tx.vout.size() << " H: " << max_used_block_height << " ms: " << a + m_fake_scan_time); + size_t mixin = tx.vin[0].type() == typeid(txin_to_key) ? boost::get<txin_to_key>(tx.vin[0]).key_offsets.size() - 1 : 0; + LOG_PRINT_L0("HASH: " << get_transaction_hash(tx) << " I/M/O: " << tx.vin.size() << "/" << mixin << "/" << tx.vout.size() << " H: " << max_used_block_height << " ms: " << a + m_fake_scan_time << " B: " << get_object_blobsize(tx)); } if (!res) return false; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index cd3ed9ab0..c2da7aaea 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -141,7 +141,6 @@ namespace cryptonote command_line::add_arg(desc, command_line::arg_fast_block_sync); command_line::add_arg(desc, command_line::arg_db_sync_mode); command_line::add_arg(desc, command_line::arg_show_time_stats); - command_line::add_arg(desc, command_line::arg_db_auto_remove_logs); command_line::add_arg(desc, command_line::arg_block_sync_size); } //----------------------------------------------------------------------------------------------- @@ -250,6 +249,8 @@ namespace cryptonote //----------------------------------------------------------------------------------------------- bool core::init(const boost::program_options::variables_map& vm, const cryptonote::test_options *test_options) { + start_time = std::time(nullptr); + m_fakechain = test_options != NULL; bool r = handle_command_line(vm); @@ -301,18 +302,6 @@ namespace cryptonote DBS_FAST_MODE = MDB_NORDAHEAD | MDB_NOSYNC; DBS_FASTEST_MODE = MDB_NORDAHEAD | MDB_NOSYNC | MDB_WRITEMAP | MDB_MAPASYNC; } - else if (db_type == "berkeley") - { -#if defined(BERKELEY_DB) - db = new BlockchainBDB(); - DBS_FAST_MODE = DB_TXN_WRITE_NOSYNC; - DBS_FASTEST_MODE = DB_TXN_NOSYNC; - DBS_SAFE_MODE = DB_TXN_SYNC; -#else - LOG_ERROR("BerkeleyDB support disabled."); - return false; -#endif - } else { LOG_ERROR("Attempted to use non-existent database type"); @@ -383,8 +372,6 @@ namespace cryptonote blocks_per_sync = bps; } - bool auto_remove_logs = command_line::get_arg(vm, command_line::arg_db_auto_remove_logs) != 0; - db->set_auto_remove_logs(auto_remove_logs); db->open(filename, db_flags); if(!db->m_open) return false; @@ -1013,6 +1000,11 @@ namespace cryptonote return m_target_blockchain_height; } //----------------------------------------------------------------------------------------------- + std::time_t core::get_start_time() const + { + return start_time; + } + //----------------------------------------------------------------------------------------------- void core::graceful_exit() { raise(SIGTERM); diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 21f84cdd4..a9e80aeee 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -560,6 +560,12 @@ namespace cryptonote uint64_t get_target_blockchain_height() const; /** + * @brief gets start_time + * + */ + std::time_t get_start_time() const; + + /** * @brief tells the Blockchain to update its checkpoints * * This function will check if enough time has passed since the last @@ -813,6 +819,8 @@ namespace cryptonote boost::interprocess::file_lock db_lock; //!< a lock object for a file lock in the db directory size_t block_sync_size; + + time_t start_time; }; } diff --git a/src/cryptonote_core/cryptonote_format_utils.h b/src/cryptonote_core/cryptonote_format_utils.h index 704b8467d..a6610e60d 100644 --- a/src/cryptonote_core/cryptonote_format_utils.h +++ b/src/cryptonote_core/cryptonote_format_utils.h @@ -36,7 +36,8 @@ #include "crypto/crypto.h" #include "crypto/hash.h" #include "ringct/rctOps.h" - +#include <boost/serialization/vector.hpp> +#include <boost/serialization/utility.hpp> namespace cryptonote { @@ -62,16 +63,6 @@ namespace cryptonote rct::key mask; //ringct amount mask void push_output(uint64_t idx, const crypto::public_key &k, uint64_t amount) { outputs.push_back(std::make_pair(idx, rct::ctkey({rct::pk2rct(k), rct::zeroCommit(amount)}))); } - - BEGIN_SERIALIZE_OBJECT() - FIELD(outputs) - VARINT_FIELD(real_output) - FIELD(real_out_tx_key) - VARINT_FIELD(real_output_in_tx_index) - VARINT_FIELD(amount) - FIELD(rct) - FIELD(mask) - END_SERIALIZE() }; struct tx_destination_entry @@ -261,3 +252,23 @@ namespace cryptonote specific_type& variable_name = boost::get<specific_type>(variant_var); } + +BOOST_CLASS_VERSION(cryptonote::tx_source_entry, 0) + +namespace boost +{ + namespace serialization + { + template <class Archive> + inline void serialize(Archive &a, cryptonote::tx_source_entry &x, const boost::serialization::version_type ver) + { + a & x.outputs; + a & x.real_output; + a & x.real_out_tx_key; + a & x.real_output_in_tx_index; + a & x.amount; + a & x.rct; + a & x.mask; + } + } +} diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 4cfd61f9f..59ac534fe 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -60,6 +60,7 @@ namespace cryptonote size_t const TRANSACTION_SIZE_LIMIT_V2 = (((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE_V2 * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE); time_t const MIN_RELAY_TIME = (60 * 5); // only start re-relaying transactions after that many seconds time_t const MAX_RELAY_TIME = (60 * 60 * 4); // at most that many seconds between resends + float const ACCEPT_THRESHOLD = 0.99f; // a kind of increasing backoff within min/max bounds time_t get_relay_delay(time_t now, time_t received) @@ -69,6 +70,11 @@ namespace cryptonote d = MAX_RELAY_TIME; return d; } + + uint64_t template_accept_threshold(uint64_t amount) + { + return amount * ACCEPT_THRESHOLD; + } } //--------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- @@ -189,6 +195,8 @@ namespace cryptonote txd_p.first->second.fee = fee; txd_p.first->second.max_used_block_id = null_hash; txd_p.first->second.max_used_block_height = 0; + txd_p.first->second.last_failed_height = 0; + txd_p.first->second.last_failed_id = null_hash; txd_p.first->second.kept_by_block = kept_by_block; txd_p.first->second.receive_time = time(nullptr); txd_p.first->second.last_relayed_time = time(NULL); @@ -585,7 +593,7 @@ namespace cryptonote } //--------------------------------------------------------------------------------- //TODO: investigate whether boolean return is appropriate - 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) + 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, uint8_t version) { // Warning: This function takes already_generated_ // coins as an argument and appears to do nothing @@ -593,47 +601,51 @@ namespace cryptonote CRITICAL_REGION_LOCAL(m_transactions_lock); + uint64_t best_coinbase = 0; total_size = 0; fee = 0; - // Maximum block size is 130% of the median block size. This gives a - // little extra headroom for the max size transaction. - size_t max_total_size = (130 * median_size) / 100 - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; + size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; std::unordered_set<crypto::key_image> k_images; + LOG_PRINT_L2("Filling block template, median size " << median_size << ", " << m_txs_by_fee.size() << " txes in the pool"); auto sorted_it = m_txs_by_fee.begin(); while (sorted_it != m_txs_by_fee.end()) { auto tx_it = m_transactions.find(sorted_it->second); + LOG_PRINT_L2("Considering " << tx_it->first << ", size " << tx_it->second.blob_size << ", current block size " << total_size << "/" << max_total_size << ", current coinbase " << print_money(best_coinbase)); // Can not exceed maximum block size if (max_total_size < total_size + tx_it->second.blob_size) { + LOG_PRINT_L2(" would exceed maximum block size"); sorted_it++; continue; } - // If adding this tx will make the block size - // greater than CRYPTONOTE_GETBLOCKTEMPLATE_MAX - // _BLOCK_SIZE bytes, reject the tx; this will - // keep block sizes from becoming too unwieldly - // to propagate at 60s block times. - if ( (total_size + tx_it->second.blob_size) > CRYPTONOTE_GETBLOCKTEMPLATE_MAX_BLOCK_SIZE ) + // If we're getting lower coinbase tx, + // stop including more tx + uint64_t block_reward; + if(!get_block_reward(median_size, total_size + tx_it->second.blob_size, already_generated_coins, block_reward, version)) { + LOG_PRINT_L2(" would exceed maximum block size"); + sorted_it++; + continue; + } + uint64_t coinbase = block_reward + fee; + if (coinbase < template_accept_threshold(best_coinbase)) + { + LOG_PRINT_L2(" would decrease coinbase to " << print_money(coinbase)); sorted_it++; continue; } - - // If we've exceeded the penalty free size, - // stop including more tx - if (total_size > median_size) - break; // Skip transactions that are not ready to be // included into the blockchain or that are // missing key images if (!is_transaction_ready_to_go(tx_it->second) || have_key_images(k_images, tx_it->second.tx)) { + LOG_PRINT_L2(" not ready to go, or key images already seen"); sorted_it++; continue; } @@ -641,10 +653,15 @@ namespace cryptonote bl.tx_hashes.push_back(tx_it->first); total_size += tx_it->second.blob_size; fee += tx_it->second.fee; + best_coinbase = coinbase; append_key_images(k_images, tx_it->second.tx); sorted_it++; + LOG_PRINT_L2(" added, new block size " << total_size << "/" << max_total_size << ", coinbase " << print_money(best_coinbase)); } + LOG_PRINT_L2("Block template filled with " << bl.tx_hashes.size() << " txes, size " + << total_size << "/" << max_total_size << ", coinbase " << print_money(best_coinbase) + << " (including " << print_money(fee) << " in fees)"); return true; } //--------------------------------------------------------------------------------- diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 794b86719..32a05b0f4 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -216,10 +216,11 @@ namespace cryptonote * @param already_generated_coins the current total number of coins "minted" * @param total_size return-by-reference the total size of the new block * @param fee return-by-reference the total of fees from the included transactions + * @param version hard fork version to use for consensus rules * * @return true */ - bool fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee); + bool fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee, uint8_t version); /** * @brief get a list of all transactions in the pool |