aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h5
-rw-r--r--src/cryptonote_basic/miner.cpp4
-rw-r--r--src/cryptonote_core/tx_pool.cpp2
-rw-r--r--src/cryptonote_core/tx_pool.h2
-rw-r--r--src/p2p/net_node.inl4
-rw-r--r--src/simplewallet/simplewallet.cpp51
-rw-r--r--src/simplewallet/simplewallet.h2
-rw-r--r--src/wallet/wallet2.cpp46
-rw-r--r--src/wallet/wallet2.h6
-rw-r--r--tests/unit_tests/node_server.cpp10
10 files changed, 117 insertions, 15 deletions
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index 41f01e9a0..5774c0ba7 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -272,6 +272,11 @@ public:
bool add_invoke_response_handler(const callback_t &cb, uint64_t timeout, async_protocol_handler& con, int command)
{
CRITICAL_REGION_LOCAL(m_invoke_response_handlers_lock);
+ if (m_protocol_released)
+ {
+ MERROR("Adding response handler to a released object");
+ return false;
+ }
boost::shared_ptr<invoke_response_handler_base> handler(boost::make_shared<anvoke_handler<callback_t>>(cb, timeout, con, command));
m_invoke_response_handlers.push_back(handler);
return handler->is_timer_started();
diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp
index 0188bf114..c4b5c8455 100644
--- a/src/cryptonote_basic/miner.cpp
+++ b/src/cryptonote_basic/miner.cpp
@@ -62,7 +62,9 @@
#include <devstat.h>
#include <errno.h>
#include <fcntl.h>
+#if defined(__amd64__) || defined(__i386__) || defined(__x86_64__)
#include <machine/apm_bios.h>
+#endif
#include <stdio.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
@@ -1086,6 +1088,7 @@ namespace cryptonote
return boost::logic::tribool(boost::logic::indeterminate);
}
+#if defined(__amd64__) || defined(__i386__) || defined(__x86_64__)
apm_info info;
if( ioctl(fd, APMIO_GETINFO, &info) == -1 ) {
close(fd);
@@ -1126,6 +1129,7 @@ namespace cryptonote
LOG_ERROR("sysctlbyname(\"hw.acpi.acline\") output is unexpectedly "
<< n << " bytes instead of the expected " << sizeof(ac) << " bytes.");
return boost::logic::tribool(boost::logic::indeterminate);
+#endif
}
return boost::logic::tribool(ac == 0);
#endif
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 0b7e5c199..3a6a3833d 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -911,7 +911,7 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::check_for_key_images(const std::vector<crypto::key_image>& key_images, std::vector<bool> spent) const
+ bool tx_memory_pool::check_for_key_images(const std::vector<crypto::key_image>& key_images, std::vector<bool>& spent) const
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index 895014d17..99182cd0d 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -301,7 +301,7 @@ namespace cryptonote
*
* @return true
*/
- bool check_for_key_images(const std::vector<crypto::key_image>& key_images, std::vector<bool> spent) const;
+ bool check_for_key_images(const std::vector<crypto::key_image>& key_images, std::vector<bool>& spent) const;
/**
* @brief get a specific transaction from the pool
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 4be6819cb..5fccdca5a 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -1864,7 +1864,11 @@ namespace nodetool
const epee::net_utils::ipv4_network_address &ipv4 = na.as<const epee::net_utils::ipv4_network_address>();
if (ipv4.ip() == 0)
ignore = true;
+ else if (ipv4.port() == be.rpc_port)
+ ignore = true;
}
+ if (be.pruning_seed && (be.pruning_seed < tools::make_pruning_seed(1, CRYPTONOTE_PRUNING_LOG_STRIPES) || be.pruning_seed > tools::make_pruning_seed(1ul << CRYPTONOTE_PRUNING_LOG_STRIPES, CRYPTONOTE_PRUNING_LOG_STRIPES)))
+ ignore = true;
if (ignore)
{
MDEBUG("Ignoring " << be.adr.str());
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index dcd3179f8..0174104be 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -2154,8 +2154,8 @@ bool simple_wallet::welcome(const std::vector<std::string> &args)
message_writer() << tr("Welcome to Monero, the private cryptocurrency.");
message_writer() << "";
message_writer() << tr("Monero, like Bitcoin, is a cryptocurrency. That is, it is digital money.");
- message_writer() << tr("Unlike Bitcoin, your Monero transactions and balance stay private, and not visible to the world by default.");
- message_writer() << tr("However, you have the option of making those available to select parties, if you choose to.");
+ message_writer() << tr("Unlike Bitcoin, your Monero transactions and balance stay private and are not visible to the world by default.");
+ message_writer() << tr("However, you have the option of making those available to select parties if you choose to.");
message_writer() << "";
message_writer() << tr("Monero protects your privacy on the blockchain, and while Monero strives to improve all the time,");
message_writer() << tr("no privacy technology can be 100% perfect, Monero included.");
@@ -2163,7 +2163,7 @@ bool simple_wallet::welcome(const std::vector<std::string> &args)
message_writer() << tr("Flaws in Monero may be discovered in the future, and attacks may be developed to peek under some");
message_writer() << tr("of the layers of privacy Monero provides. Be safe and practice defense in depth.");
message_writer() << "";
- message_writer() << tr("Welcome to Monero and financial privacy. For more information, see https://getmonero.org/");
+ message_writer() << tr("Welcome to Monero and financial privacy. For more information see https://GetMonero.org");
return true;
}
@@ -2659,6 +2659,43 @@ bool simple_wallet::set_ignore_fractional_outputs(const std::vector<std::string>
return true;
}
+
+bool simple_wallet::set_ignore_outputs_above(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
+{
+ const auto pwd_container = get_and_verify_password();
+ if (pwd_container)
+ {
+ uint64_t amount;
+ if (!cryptonote::parse_amount(amount, args[1]))
+ {
+ fail_msg_writer() << tr("Invalid amount");
+ return true;
+ }
+ if (amount == 0)
+ amount = MONEY_SUPPLY;
+ m_wallet->ignore_outputs_above(amount);
+ m_wallet->rewrite(m_wallet_file, pwd_container->password());
+ }
+ return true;
+}
+
+bool simple_wallet::set_ignore_outputs_below(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
+{
+ const auto pwd_container = get_and_verify_password();
+ if (pwd_container)
+ {
+ uint64_t amount;
+ if (!cryptonote::parse_amount(amount, args[1]))
+ {
+ fail_msg_writer() << tr("Invalid amount");
+ return true;
+ }
+ m_wallet->ignore_outputs_below(amount);
+ m_wallet->rewrite(m_wallet_file, pwd_container->password());
+ }
+ return true;
+}
+
bool simple_wallet::set_track_uses(const std::vector<std::string> &args/* = std::vector<std::string>()*/)
{
const auto pwd_container = get_and_verify_password();
@@ -2973,6 +3010,10 @@ simple_wallet::simple_wallet()
" Set to the height of a key reusing fork you want to use, 0 to use default.\n "
"ignore-fractional-outputs <1|0>\n "
" Whether to ignore fractional outputs that result in net loss when spending due to fee.\n "
+ "ignore-outputs-above <amount>\n "
+ " Ignore outputs of amount above this threshold when spending. Value 0 is translated to the maximum value (18 million) which disables this filter.\n "
+ "ignore-outputs-below <amount>\n "
+ " Ignore outputs of amount below this threshold when spending.\n "
"track-uses <1|0>\n "
" Whether to keep track of owned outputs uses.\n "
"setup-background-mining <1|0>\n "
@@ -3349,6 +3390,8 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
success_msg_writer() << "subaddress-lookahead = " << lookahead.first << ":" << lookahead.second;
success_msg_writer() << "segregation-height = " << m_wallet->segregation_height();
success_msg_writer() << "ignore-fractional-outputs = " << m_wallet->ignore_fractional_outputs();
+ success_msg_writer() << "ignore-outputs-above = " << cryptonote::print_money(m_wallet->ignore_outputs_above());
+ success_msg_writer() << "ignore-outputs-below = " << cryptonote::print_money(m_wallet->ignore_outputs_below());
success_msg_writer() << "track-uses = " << m_wallet->track_uses();
success_msg_writer() << "setup-background-mining = " << setup_background_mining_string;
success_msg_writer() << "device-name = " << m_wallet->device_name();
@@ -3412,6 +3455,8 @@ bool simple_wallet::set_variable(const std::vector<std::string> &args)
CHECK_SIMPLE_VARIABLE("subaddress-lookahead", set_subaddress_lookahead, tr("<major>:<minor>"));
CHECK_SIMPLE_VARIABLE("segregation-height", set_segregation_height, tr("unsigned integer"));
CHECK_SIMPLE_VARIABLE("ignore-fractional-outputs", set_ignore_fractional_outputs, tr("0 or 1"));
+ CHECK_SIMPLE_VARIABLE("ignore-outputs-above", set_ignore_outputs_above, tr("amount"));
+ CHECK_SIMPLE_VARIABLE("ignore-outputs-below", set_ignore_outputs_below, tr("amount"));
CHECK_SIMPLE_VARIABLE("track-uses", set_track_uses, tr("0 or 1"));
CHECK_SIMPLE_VARIABLE("inactivity-lock-timeout", set_inactivity_lock_timeout, tr("unsigned integer (seconds, 0 to disable)"));
CHECK_SIMPLE_VARIABLE("setup-background-mining", set_setup_background_mining, tr("1/yes or 0/no"));
diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h
index bd135a9c1..47e08ca87 100644
--- a/src/simplewallet/simplewallet.h
+++ b/src/simplewallet/simplewallet.h
@@ -144,6 +144,8 @@ namespace cryptonote
bool set_subaddress_lookahead(const std::vector<std::string> &args = std::vector<std::string>());
bool set_segregation_height(const std::vector<std::string> &args = std::vector<std::string>());
bool set_ignore_fractional_outputs(const std::vector<std::string> &args = std::vector<std::string>());
+ bool set_ignore_outputs_above(const std::vector<std::string> &args = std::vector<std::string>());
+ bool set_ignore_outputs_below(const std::vector<std::string> &args = std::vector<std::string>());
bool set_track_uses(const std::vector<std::string> &args = std::vector<std::string>());
bool set_inactivity_lock_timeout(const std::vector<std::string> &args = std::vector<std::string>());
bool set_setup_background_mining(const std::vector<std::string> &args = std::vector<std::string>());
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index f3c7152e2..c7374b896 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -1128,6 +1128,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
m_key_reuse_mitigation2(true),
m_segregation_height(0),
m_ignore_fractional_outputs(true),
+ m_ignore_outputs_above(MONEY_SUPPLY),
+ m_ignore_outputs_below(0),
m_track_uses(false),
m_inactivity_lock_timeout(DEFAULT_INACTIVITY_LOCK_TIMEOUT),
m_setup_background_mining(BackgroundMiningMaybe),
@@ -3695,6 +3697,12 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable
value2.SetInt(m_ignore_fractional_outputs ? 1 : 0);
json.AddMember("ignore_fractional_outputs", value2, json.GetAllocator());
+ value2.SetUint64(m_ignore_outputs_above);
+ json.AddMember("ignore_outputs_above", value2, json.GetAllocator());
+
+ value2.SetUint64(m_ignore_outputs_below);
+ json.AddMember("ignore_outputs_below", value2, json.GetAllocator());
+
value2.SetInt(m_track_uses ? 1 : 0);
json.AddMember("track_uses", value2, json.GetAllocator());
@@ -3855,6 +3863,8 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_key_reuse_mitigation2 = true;
m_segregation_height = 0;
m_ignore_fractional_outputs = true;
+ m_ignore_outputs_above = MONEY_SUPPLY;
+ m_ignore_outputs_below = 0;
m_track_uses = false;
m_inactivity_lock_timeout = DEFAULT_INACTIVITY_LOCK_TIMEOUT;
m_setup_background_mining = BackgroundMiningMaybe;
@@ -4009,6 +4019,10 @@ bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_
m_segregation_height = field_segregation_height;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ignore_fractional_outputs, int, Int, false, true);
m_ignore_fractional_outputs = field_ignore_fractional_outputs;
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ignore_outputs_above, uint64_t, Uint64, false, MONEY_SUPPLY);
+ m_ignore_outputs_above = field_ignore_outputs_above;
+ GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, ignore_outputs_below, uint64_t, Uint64, false, 0);
+ m_ignore_outputs_below = field_ignore_outputs_below;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, track_uses, int, Int, false, false);
m_track_uses = field_track_uses;
GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, inactivity_lock_timeout, uint32_t, Uint, false, DEFAULT_INACTIVITY_LOCK_TIMEOUT);
@@ -5575,6 +5589,11 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas
const std::string address_file = m_wallet_file + ".address.txt";
r = save_to_file(address_file, m_account.get_public_address_str(m_nettype), true);
THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file);
+ // remove old address file
+ r = boost::filesystem::remove(old_address_file);
+ if (!r) {
+ LOG_ERROR("error removing file: " << old_address_file);
+ }
}
// remove old wallet file
r = boost::filesystem::remove(old_file);
@@ -5586,11 +5605,6 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas
if (!r) {
LOG_ERROR("error removing file: " << old_keys_file);
}
- // remove old address file
- r = boost::filesystem::remove(old_address_file);
- if (!r) {
- LOG_ERROR("error removing file: " << old_address_file);
- }
// remove old message store file
if (boost::filesystem::exists(old_mms_file))
{
@@ -8604,6 +8618,11 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
const transfer_details& td = m_transfers[i];
if (!is_spent(td, false) && !td.m_frozen && td.is_rct() && td.amount() >= needed_money && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
{
+ if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below)
+ {
+ MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]");
+ continue;
+ }
LOG_PRINT_L2("We can use " << i << " alone: " << print_money(td.amount()));
picks.push_back(i);
return picks;
@@ -8619,10 +8638,20 @@ std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, ui
const transfer_details& td = m_transfers[i];
if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && td.is_rct() && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
{
+ if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below)
+ {
+ MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]");
+ continue;
+ }
LOG_PRINT_L2("Considering input " << i << ", " << print_money(td.amount()));
for (size_t j = i + 1; j < m_transfers.size(); ++j)
{
const transfer_details& td2 = m_transfers[j];
+ if (td2.amount() > m_ignore_outputs_above || td2.amount() < m_ignore_outputs_below)
+ {
+ MDEBUG("Ignoring output " << j << " of amount " << print_money(td2.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]");
+ continue;
+ }
if (!is_spent(td2, false) && !td2.m_frozen && !td.m_key_image_partial && td2.is_rct() && td.amount() + td2.amount() >= needed_money && is_transfer_unlocked(td2) && td2.m_subaddr_index == td.m_subaddr_index)
{
// update our picks if those outputs are less related than any we
@@ -9322,11 +9351,16 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
const transfer_details& td = m_transfers[i];
if (m_ignore_fractional_outputs && td.amount() < fractional_threshold)
{
- MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below threshold " << print_money(fractional_threshold));
+ MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is below fractional threshold " << print_money(fractional_threshold));
continue;
}
if (!is_spent(td, false) && !td.m_frozen && !td.m_key_image_partial && (use_rct ? true : !td.is_rct()) && is_transfer_unlocked(td) && td.m_subaddr_index.major == subaddr_account && subaddr_indices.count(td.m_subaddr_index.minor) == 1)
{
+ if (td.amount() > m_ignore_outputs_above || td.amount() < m_ignore_outputs_below)
+ {
+ MDEBUG("Ignoring output " << i << " of amount " << print_money(td.amount()) << " which is outside prescribed range [" << print_money(m_ignore_outputs_below) << ", " << print_money(m_ignore_outputs_above) << "]");
+ continue;
+ }
const uint32_t index_minor = td.m_subaddr_index.minor;
auto find_predicate = [&index_minor](const std::pair<uint32_t, std::vector<size_t>>& x) { return x.first == index_minor; };
if ((td.is_rct()) || is_valid_decomposed_amount(td.amount()))
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index 291e6e3d7..52118c426 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1045,6 +1045,10 @@ private:
void ignore_fractional_outputs(bool value) { m_ignore_fractional_outputs = value; }
bool confirm_non_default_ring_size() const { return m_confirm_non_default_ring_size; }
void confirm_non_default_ring_size(bool always) { m_confirm_non_default_ring_size = always; }
+ uint64_t ignore_outputs_above() const { return m_ignore_outputs_above; }
+ void ignore_outputs_above(uint64_t value) { m_ignore_outputs_above = value; }
+ uint64_t ignore_outputs_below() const { return m_ignore_outputs_below; }
+ void ignore_outputs_below(uint64_t value) { m_ignore_outputs_below = value; }
bool track_uses() const { return m_track_uses; }
void track_uses(bool value) { m_track_uses = value; }
BackgroundMiningSetupType setup_background_mining() const { return m_setup_background_mining; }
@@ -1507,6 +1511,8 @@ private:
bool m_key_reuse_mitigation2;
uint64_t m_segregation_height;
bool m_ignore_fractional_outputs;
+ uint64_t m_ignore_outputs_above;
+ uint64_t m_ignore_outputs_below;
bool m_track_uses;
uint32_t m_inactivity_lock_timeout;
BackgroundMiningSetupType m_setup_background_mining;
diff --git a/tests/unit_tests/node_server.cpp b/tests/unit_tests/node_server.cpp
index 2cf66ccec..2c89323c7 100644
--- a/tests/unit_tests/node_server.cpp
+++ b/tests/unit_tests/node_server.cpp
@@ -56,13 +56,13 @@ public:
bool get_stat_info(cryptonote::core_stat_info& st_inf) const {return true;}
bool have_block(const crypto::hash& id) const {return true;}
void get_blockchain_top(uint64_t& height, crypto::hash& top_id)const{height=0;top_id=crypto::null_hash;}
- bool handle_incoming_tx(const cryptonote::blobdata& tx_blob, cryptonote::tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { return true; }
- bool handle_incoming_txs(const std::vector<cryptonote::blobdata>& tx_blob, std::vector<cryptonote::tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { return true; }
+ bool handle_incoming_tx(const cryptonote::tx_blob_entry& tx_blob, cryptonote::tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { return true; }
+ bool handle_incoming_txs(const std::vector<cryptonote::tx_blob_entry>& tx_blob, std::vector<cryptonote::tx_verification_context>& tvc, bool keeped_by_block, bool relayed, bool do_not_relay) { return true; }
bool handle_incoming_block(const cryptonote::blobdata& block_blob, const cryptonote::block *block, cryptonote::block_verification_context& bvc, bool update_miner_blocktemplate = true) { return true; }
void pause_mine(){}
void resume_mine(){}
bool on_idle(){return true;}
- bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;}
+ bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, bool clip_pruned, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;}
bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;}
cryptonote::blockchain_storage &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class test_core."); }
bool get_test_drop_download() const {return true;}
@@ -84,10 +84,12 @@ public:
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const { return 0; }
cryptonote::difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return 0; }
bool fluffy_blocks_enabled() const { return false; }
- uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes) { return 0; }
+ uint64_t prevalidate_block_hashes(uint64_t height, const std::vector<crypto::hash> &hashes, const std::vector<uint64_t> &weights) { return 0; }
bool pad_transactions() { return false; }
uint32_t get_blockchain_pruning_seed() const { return 0; }
bool prune_blockchain(uint32_t pruning_seed = 0) { return true; }
+ bool is_within_compiled_block_hash_area(uint64_t height) const { return false; }
+ bool has_block_weights(uint64_t height, uint64_t nblocks) const { return false; }
void stop() {}
};