aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core')
-rw-r--r--src/cryptonote_core/account.cpp8
-rw-r--r--src/cryptonote_core/blockchain.cpp24
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp22
-rw-r--r--src/cryptonote_core/cryptonote_core.h8
-rw-r--r--src/cryptonote_core/cryptonote_format_utils.h33
-rw-r--r--src/cryptonote_core/tx_pool.cpp47
-rw-r--r--src/cryptonote_core/tx_pool.h3
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(&timestamp);
+ 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(&timestamp);
+ 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