aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core/cryptonote_core.cpp
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-09-16 12:18:34 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2019-09-27 00:10:37 +0000
commit8330e772f1ed680a54833d25c4d17d09a99ab8d6 (patch)
treed536126b06a00fabd56881363daaa9a1fd305c80 /src/cryptonote_core/cryptonote_core.cpp
parentd0d76f771ac318046306cd2ef40e67d598d7429d (diff)
downloadmonzero-core-8330e772f1ed680a54833d25c4d17d09a99ab8d6.tar.gz
monzero-core-8330e772f1ed680a54833d25c4d17d09a99ab8d6.tar.xz
monzero-core-8330e772f1ed680a54833d25c4d17d09a99ab8d6.zip
monerod can now sync from pruned blocks
If the peer (whether pruned or not itself) supports sending pruned blocks to syncing nodes, the pruned version will be sent along with the hash of the pruned data and the block weight. The original tx hashes can be reconstructed from the pruned txes and theur prunable data hash. Those hashes and the block weights are hashes and checked against the set of precompiled hashes, ensuring the data we received is the original data. It is currently not possible to use this system when not using the set of precompiled hashes, since block weights can not otherwise be checked for validity. This is off by default for now, and is enabled by --sync-pruned-blocks
Diffstat (limited to 'src/cryptonote_core/cryptonote_core.cpp')
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp75
1 files changed, 58 insertions, 17 deletions
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index a3a92ab60..785ee7db4 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -113,6 +113,10 @@ namespace cryptonote
, "Set maximum size of block download queue in bytes (0 for default)"
, 0
};
+ const command_line::arg_descriptor<bool> arg_sync_pruned_blocks = {
+ "sync-pruned-blocks"
+ , "Allow syncing from nodes with only pruned blocks"
+ };
static const command_line::arg_descriptor<bool> arg_test_drop_download = {
"test-drop-download"
@@ -323,6 +327,7 @@ namespace cryptonote
command_line::add_arg(desc, arg_offline);
command_line::add_arg(desc, arg_disable_dns_checkpoints);
command_line::add_arg(desc, arg_block_download_max_size);
+ command_line::add_arg(desc, arg_sync_pruned_blocks);
command_line::add_arg(desc, arg_max_txpool_weight);
command_line::add_arg(desc, arg_pad_transactions);
command_line::add_arg(desc, arg_block_notify);
@@ -744,13 +749,13 @@ namespace cryptonote
return false;
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_tx_pre(const blobdata& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_tx_pre(const tx_blob_entry& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, bool keeped_by_block, bool relayed, bool do_not_relay)
{
tvc = boost::value_initialized<tx_verification_context>();
- if(tx_blob.size() > get_max_tx_size())
+ if(tx_blob.blob.size() > get_max_tx_size())
{
- LOG_PRINT_L1("WRONG TRANSACTION BLOB, too big size " << tx_blob.size() << ", rejected");
+ LOG_PRINT_L1("WRONG TRANSACTION BLOB, too big size " << tx_blob.blob.size() << ", rejected");
tvc.m_verifivation_failed = true;
tvc.m_too_big = true;
return false;
@@ -758,7 +763,23 @@ namespace cryptonote
tx_hash = crypto::null_hash;
- if(!parse_tx_from_blob(tx, tx_hash, tx_blob))
+ bool r;
+ if (tx_blob.prunable_hash == crypto::null_hash)
+ {
+ r = parse_tx_from_blob(tx, tx_hash, tx_blob.blob);
+ }
+ else
+ {
+ r = parse_and_validate_tx_base_from_blob(tx_blob.blob, tx);
+ if (r)
+ {
+ tx.set_prunable_hash(tx_blob.prunable_hash);
+ tx_hash = cryptonote::get_pruned_transaction_hash(tx, tx_blob.prunable_hash);
+ tx.set_hash(tx_hash);
+ }
+ }
+
+ if (!r)
{
LOG_PRINT_L1("WRONG TRANSACTION BLOB, Failed to parse, rejected");
tvc.m_verifivation_failed = true;
@@ -784,6 +805,7 @@ namespace cryptonote
if (tx.version == 0 || tx.version > max_tx_version)
{
// v2 is the latest one we know
+ MERROR_VER("Bad tx version (" << tx.version << ", max is " << max_tx_version << ")");
tvc.m_verifivation_failed = true;
return false;
}
@@ -791,7 +813,7 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_tx_post(const blobdata& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_tx_post(const tx_blob_entry& tx_blob, tx_verification_context& tvc, cryptonote::transaction &tx, crypto::hash &tx_hash, bool keeped_by_block, bool relayed, bool do_not_relay)
{
if(!check_tx_syntax(tx))
{
@@ -920,7 +942,7 @@ namespace cryptonote
return ret;
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_txs(const std::vector<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_txs(const std::vector<tx_blob_entry>& tx_blobs, std::vector<tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
{
TRY_ENTRY();
CRITICAL_REGION_LOCAL(m_incoming_tx_lock);
@@ -931,7 +953,7 @@ namespace cryptonote
tvc.resize(tx_blobs.size());
tools::threadpool& tpool = tools::threadpool::getInstance();
tools::threadpool::waiter waiter;
- std::vector<blobdata>::const_iterator it = tx_blobs.begin();
+ std::vector<tx_blob_entry>::const_iterator it = tx_blobs.begin();
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
tpool.submit(&waiter, [&, i, it] {
try
@@ -1003,8 +1025,12 @@ namespace cryptonote
if (already_have[i])
continue;
- const size_t weight = get_transaction_weight(results[i].tx, it->size());
- ok &= add_new_tx(results[i].tx, results[i].hash, tx_blobs[i], weight, tvc[i], keeped_by_block, relayed, do_not_relay);
+ // if it's a pruned tx from an incoming block, we'll get a weight that's technically
+ // different from the actual transaction weight, but it's OK for our use. Those txes
+ // will be ignored when mining, and using that "pruned" weight seems appropriate for
+ // keeping the txpool size constrained
+ const uint64_t weight = results[i].tx.pruned ? 0 : get_transaction_weight(results[i].tx, it->blob.size());
+ ok &= add_new_tx(results[i].tx, results[i].hash, tx_blobs[i].blob, weight, tvc[i], keeped_by_block, relayed, do_not_relay);
if(tvc[i].m_verifivation_failed)
{MERROR_VER("Transaction verification failed: " << results[i].hash);}
else if(tvc[i].m_verifivation_impossible)
@@ -1018,9 +1044,9 @@ namespace cryptonote
CATCH_ENTRY_L0("core::handle_incoming_txs()", false);
}
//-----------------------------------------------------------------------------------------------
- bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
+ bool core::handle_incoming_tx(const tx_blob_entry& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
{
- std::vector<cryptonote::blobdata> tx_blobs;
+ std::vector<tx_blob_entry> tx_blobs;
tx_blobs.push_back(tx_blob);
std::vector<tx_verification_context> tvcv(1);
bool r = handle_incoming_txs(tx_blobs, tvcv, keeped_by_block, relayed, do_not_relay);
@@ -1028,6 +1054,11 @@ namespace cryptonote
return r;
}
//-----------------------------------------------------------------------------------------------
+ bool core::handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
+ {
+ return handle_incoming_tx({tx_blob, crypto::null_hash}, tvc, keeped_by_block, relayed, do_not_relay);
+ }
+ //-----------------------------------------------------------------------------------------------
bool core::get_stat_info(core_stat_info& st_inf) const
{
st_inf.mining_speed = m_miner.get_speed();
@@ -1290,9 +1321,9 @@ namespace cryptonote
return m_blockchain_storage.create_block_template(b, prev_block, adr, diffic, height, expected_reward, ex_nonce);
}
//-----------------------------------------------------------------------------------------------
- bool core::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const
+ bool core::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, bool clip_pruned, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const
{
- return m_blockchain_storage.find_blockchain_supplement(qblock_ids, resp);
+ return m_blockchain_storage.find_blockchain_supplement(qblock_ids, clip_pruned, resp);
}
//-----------------------------------------------------------------------------------------------
bool core::find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >& blocks, uint64_t& total_height, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, size_t max_count) const
@@ -1338,7 +1369,7 @@ namespace cryptonote
{
cryptonote::blobdata txblob;
CHECK_AND_ASSERT_THROW_MES(pool.get_transaction(tx_hash, txblob), "Transaction not found in pool");
- bce.txs.push_back(txblob);
+ bce.txs.push_back({txblob, crypto::null_hash});
}
return bce;
}
@@ -1391,7 +1422,7 @@ namespace cryptonote
block_to_blob(b, arg.b.block);
//pack transactions
for(auto& tx: txs)
- arg.b.txs.push_back(tx);
+ arg.b.txs.push_back({tx, crypto::null_hash});
m_pprotocol->relay_block(arg, exclude_context);
}
@@ -1901,9 +1932,9 @@ namespace cryptonote
return m_target_blockchain_height;
}
//-----------------------------------------------------------------------------------------------
- uint64_t core::prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes)
+ uint64_t core::prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes, const std::vector<uint64_t> &weights)
{
- return get_blockchain_storage().prevalidate_block_hashes(height, hashes);
+ return get_blockchain_storage().prevalidate_block_hashes(height, hashes, weights);
}
//-----------------------------------------------------------------------------------------------
uint64_t core::get_free_space() const
@@ -1923,6 +1954,16 @@ namespace cryptonote
return get_blockchain_storage().prune_blockchain(pruning_seed);
}
//-----------------------------------------------------------------------------------------------
+ bool core::is_within_compiled_block_hash_area(uint64_t height) const
+ {
+ return get_blockchain_storage().is_within_compiled_block_hash_area(height);
+ }
+ //-----------------------------------------------------------------------------------------------
+ bool core::has_block_weights(uint64_t height, uint64_t nblocks) const
+ {
+ return get_blockchain_storage().has_block_weights(height, nblocks);
+ }
+ //-----------------------------------------------------------------------------------------------
std::time_t core::get_start_time() const
{
return start_time;