wallet2: adapt to deterministic unlock time

This commit is contained in:
TheCharlatan 2020-08-02 15:54:29 +00:00 committed by moneromooo-monero
parent 4971219c2c
commit 80e535c95a
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
10 changed files with 57 additions and 23 deletions

View file

@ -461,6 +461,8 @@ namespace cryptonote
res.cumulative_difficulty, res.wide_cumulative_difficulty, res.cumulative_difficulty_top64); res.cumulative_difficulty, res.wide_cumulative_difficulty, res.cumulative_difficulty_top64);
res.block_size_limit = res.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit(); res.block_size_limit = res.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit();
res.block_size_median = res.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median(); res.block_size_median = res.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median();
res.adjusted_time = m_core.get_blockchain_storage().get_adjusted_time(res.height);
res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time(); res.start_time = restricted ? 0 : (uint64_t)m_core.get_start_time();
res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space(); res.free_space = restricted ? std::numeric_limits<uint64_t>::max() : m_core.get_free_space();
res.offline = m_core.offline(); res.offline = m_core.offline();

View file

@ -88,7 +88,7 @@ namespace cryptonote
// advance which version they will stop working with // advance which version they will stop working with
// Don't go over 32767 for any of these // Don't go over 32767 for any of these
#define CORE_RPC_VERSION_MAJOR 3 #define CORE_RPC_VERSION_MAJOR 3
#define CORE_RPC_VERSION_MINOR 1 #define CORE_RPC_VERSION_MINOR 2
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR) #define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
@ -675,6 +675,7 @@ namespace cryptonote
uint64_t block_weight_limit; uint64_t block_weight_limit;
uint64_t block_size_median; uint64_t block_size_median;
uint64_t block_weight_median; uint64_t block_weight_median;
uint64_t adjusted_time;
uint64_t start_time; uint64_t start_time;
uint64_t free_space; uint64_t free_space;
bool offline; bool offline;
@ -713,6 +714,7 @@ namespace cryptonote
KV_SERIALIZE_OPT(block_weight_limit, (uint64_t)0) KV_SERIALIZE_OPT(block_weight_limit, (uint64_t)0)
KV_SERIALIZE(block_size_median) KV_SERIALIZE(block_size_median)
KV_SERIALIZE_OPT(block_weight_median, (uint64_t)0) KV_SERIALIZE_OPT(block_weight_median, (uint64_t)0)
KV_SERIALIZE(adjusted_time)
KV_SERIALIZE(start_time) KV_SERIALIZE(start_time)
KV_SERIALIZE(free_space) KV_SERIALIZE(free_space)
KV_SERIALIZE(offline) KV_SERIALIZE(offline)

View file

@ -538,6 +538,7 @@ namespace rpc
res.info.cumulative_difficulty = (res.info.wide_cumulative_difficulty & 0xffffffffffffffff).convert_to<uint64_t>(); res.info.cumulative_difficulty = (res.info.wide_cumulative_difficulty & 0xffffffffffffffff).convert_to<uint64_t>();
res.info.block_size_limit = res.info.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit(); res.info.block_size_limit = res.info.block_weight_limit = m_core.get_blockchain_storage().get_current_cumulative_block_weight_limit();
res.info.block_size_median = res.info.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median(); res.info.block_size_median = res.info.block_weight_median = m_core.get_blockchain_storage().get_current_cumulative_block_weight_median();
res.info.adjusted_time = m_core.get_blockchain_storage().get_adjusted_time(res.info.height);
res.info.start_time = (uint64_t)m_core.get_start_time(); res.info.start_time = (uint64_t)m_core.get_start_time();
res.info.version = MONERO_VERSION; res.info.version = MONERO_VERSION;

View file

@ -196,6 +196,7 @@ namespace rpc
uint64_t block_size_limit; uint64_t block_size_limit;
uint64_t block_weight_limit; uint64_t block_weight_limit;
uint64_t block_size_median; uint64_t block_size_median;
uint64_t adjusted_time;
uint64_t block_weight_median; uint64_t block_weight_median;
uint64_t start_time; uint64_t start_time;
std::string version; std::string version;

View file

@ -1342,6 +1342,7 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::r
INSERT_INTO_JSON_OBJECT(dest, block_weight_limit, info.block_weight_limit); INSERT_INTO_JSON_OBJECT(dest, block_weight_limit, info.block_weight_limit);
INSERT_INTO_JSON_OBJECT(dest, block_size_median, info.block_size_median); INSERT_INTO_JSON_OBJECT(dest, block_size_median, info.block_size_median);
INSERT_INTO_JSON_OBJECT(dest, block_weight_median, info.block_weight_median); INSERT_INTO_JSON_OBJECT(dest, block_weight_median, info.block_weight_median);
INSERT_INTO_JSON_OBJECT(dest, adjusted_time, info.adjusted_time);
INSERT_INTO_JSON_OBJECT(dest, start_time, info.start_time); INSERT_INTO_JSON_OBJECT(dest, start_time, info.start_time);
dest.EndObject(); dest.EndObject();
@ -1375,6 +1376,7 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& inf
GET_FROM_JSON_OBJECT(val, info.block_weight_limit, block_weight_limit); GET_FROM_JSON_OBJECT(val, info.block_weight_limit, block_weight_limit);
GET_FROM_JSON_OBJECT(val, info.block_size_median, block_size_median); GET_FROM_JSON_OBJECT(val, info.block_size_median, block_size_median);
GET_FROM_JSON_OBJECT(val, info.block_weight_median, block_weight_median); GET_FROM_JSON_OBJECT(val, info.block_weight_median, block_weight_median);
GET_FROM_JSON_OBJECT(val, info.adjusted_time, adjusted_time);
GET_FROM_JSON_OBJECT(val, info.start_time, start_time); GET_FROM_JSON_OBJECT(val, info.start_time, start_time);
} }

View file

@ -8553,8 +8553,8 @@ bool simple_wallet::get_transfers(std::vector<std::string>& local_args, std::vec
} }
else else
{ {
uint64_t current_time = static_cast<uint64_t>(time(NULL)); const uint64_t adjusted_time = m_wallet->get_daemon_adjusted_time();
uint64_t threshold = current_time + (m_wallet->use_fork_rules(2, 0) ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1); uint64_t threshold = adjusted_time + (m_wallet->use_fork_rules(2, 0) ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1);
if (threshold < pd.m_unlock_time) if (threshold < pd.m_unlock_time)
locked_msg = get_human_readable_timespan(std::chrono::seconds(pd.m_unlock_time - threshold)); locked_msg = get_human_readable_timespan(std::chrono::seconds(pd.m_unlock_time - threshold));
} }
@ -10265,8 +10265,8 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args)
} }
else else
{ {
uint64_t current_time = static_cast<uint64_t>(time(NULL)); const uint64_t adjusted_time = m_wallet->get_daemon_adjusted_time();
uint64_t threshold = current_time + (m_wallet->use_fork_rules(2, 0) ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1); uint64_t threshold = adjusted_time + (m_wallet->use_fork_rules(2, 0) ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1);
if (threshold >= pd.m_unlock_time) if (threshold >= pd.m_unlock_time)
success_msg_writer() << "unlocked for " << get_human_readable_timespan(std::chrono::seconds(threshold - pd.m_unlock_time)); success_msg_writer() << "unlocked for " << get_human_readable_timespan(std::chrono::seconds(threshold - pd.m_unlock_time));
else else

View file

@ -72,6 +72,7 @@ void NodeRPCProxy::invalidate()
m_rpc_version = 0; m_rpc_version = 0;
m_target_height = 0; m_target_height = 0;
m_block_weight_limit = 0; m_block_weight_limit = 0;
m_adjusted_time = 0;
m_get_info_time = 0; m_get_info_time = 0;
m_rpc_payment_info_time = 0; m_rpc_payment_info_time = 0;
m_rpc_payment_seed_height = 0; m_rpc_payment_seed_height = 0;
@ -131,6 +132,7 @@ boost::optional<std::string> NodeRPCProxy::get_info()
m_height = resp_t.height; m_height = resp_t.height;
m_target_height = resp_t.target_height; m_target_height = resp_t.target_height;
m_block_weight_limit = resp_t.block_weight_limit ? resp_t.block_weight_limit : resp_t.block_size_limit; m_block_weight_limit = resp_t.block_weight_limit ? resp_t.block_weight_limit : resp_t.block_size_limit;
m_adjusted_time = resp_t.adjusted_time;
m_get_info_time = now; m_get_info_time = now;
m_height_time = now; m_height_time = now;
} }
@ -171,6 +173,15 @@ boost::optional<std::string> NodeRPCProxy::get_block_weight_limit(uint64_t &bloc
return boost::optional<std::string>(); return boost::optional<std::string>();
} }
boost::optional<std::string> NodeRPCProxy::get_adjusted_time(uint64_t &adjusted_time)
{
auto res = get_info();
if (res)
return res;
adjusted_time = m_adjusted_time;
return boost::optional<std::string>();
}
boost::optional<std::string> NodeRPCProxy::get_earliest_height(uint8_t version, uint64_t &earliest_height) boost::optional<std::string> NodeRPCProxy::get_earliest_height(uint8_t version, uint64_t &earliest_height)
{ {
if (m_offline) if (m_offline)

View file

@ -52,6 +52,7 @@ public:
void set_height(uint64_t h); void set_height(uint64_t h);
boost::optional<std::string> get_target_height(uint64_t &height); boost::optional<std::string> get_target_height(uint64_t &height);
boost::optional<std::string> get_block_weight_limit(uint64_t &block_weight_limit); boost::optional<std::string> get_block_weight_limit(uint64_t &block_weight_limit);
boost::optional<std::string> get_adjusted_time(uint64_t &adjusted_time);
boost::optional<std::string> get_earliest_height(uint8_t version, uint64_t &earliest_height); boost::optional<std::string> get_earliest_height(uint8_t version, uint64_t &earliest_height);
boost::optional<std::string> get_dynamic_base_fee_estimate(uint64_t grace_blocks, uint64_t &fee); boost::optional<std::string> get_dynamic_base_fee_estimate(uint64_t grace_blocks, uint64_t &fee);
boost::optional<std::string> get_fee_quantization_mask(uint64_t &fee_quantization_mask); boost::optional<std::string> get_fee_quantization_mask(uint64_t &fee_quantization_mask);
@ -84,6 +85,7 @@ private:
uint64_t m_dynamic_base_fee_estimate_cached_height; uint64_t m_dynamic_base_fee_estimate_cached_height;
uint64_t m_dynamic_base_fee_estimate_grace_blocks; uint64_t m_dynamic_base_fee_estimate_grace_blocks;
uint64_t m_fee_quantization_mask; uint64_t m_fee_quantization_mask;
uint64_t m_adjusted_time;
uint32_t m_rpc_version; uint32_t m_rpc_version;
uint64_t m_target_height; uint64_t m_target_height;
uint64_t m_block_weight_limit; uint64_t m_block_weight_limit;

View file

@ -5969,7 +5969,7 @@ uint64_t wallet2::balance(uint32_t index_major, bool strict) const
return amount; return amount;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock) const uint64_t wallet2::unlocked_balance(uint32_t index_major, bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock)
{ {
uint64_t amount = 0; uint64_t amount = 0;
if (blocks_to_unlock) if (blocks_to_unlock)
@ -6021,7 +6021,7 @@ std::map<uint32_t, uint64_t> wallet2::balance_per_subaddress(uint32_t index_majo
return amount_per_subaddr; return amount_per_subaddr;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> wallet2::unlocked_balance_per_subaddress(uint32_t index_major, bool strict) const std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> wallet2::unlocked_balance_per_subaddress(uint32_t index_major, bool strict)
{ {
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> amount_per_subaddr; std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> amount_per_subaddr;
const uint64_t blockchain_height = get_blockchain_current_height(); const uint64_t blockchain_height = get_blockchain_current_height();
@ -6069,7 +6069,7 @@ uint64_t wallet2::balance_all(bool strict) const
return r; return r;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
uint64_t wallet2::unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock) const uint64_t wallet2::unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock, uint64_t *time_to_unlock)
{ {
uint64_t r = 0; uint64_t r = 0;
if (blocks_to_unlock) if (blocks_to_unlock)
@ -6234,12 +6234,12 @@ void wallet2::rescan_blockchain(bool hard, bool refresh, bool keep_key_images)
finish_rescan_bc_keep_key_images(transfers_cnt, transfers_hash); finish_rescan_bc_keep_key_images(transfers_cnt, transfers_hash);
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool wallet2::is_transfer_unlocked(const transfer_details& td) const bool wallet2::is_transfer_unlocked(const transfer_details& td)
{ {
return is_transfer_unlocked(td.m_tx.unlock_time, td.m_block_height); return is_transfer_unlocked(td.m_tx.unlock_time, td.m_block_height);
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool wallet2::is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height) const bool wallet2::is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height)
{ {
if(!is_tx_spendtime_unlocked(unlock_time, block_height)) if(!is_tx_spendtime_unlocked(unlock_time, block_height))
return false; return false;
@ -6250,7 +6250,7 @@ bool wallet2::is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height)
return true; return true;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
bool wallet2::is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height) const bool wallet2::is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height)
{ {
if(unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER) if(unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER)
{ {
@ -6262,12 +6262,14 @@ bool wallet2::is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_heig
}else }else
{ {
//interpret as time //interpret as time
uint64_t current_time = static_cast<uint64_t>(time(NULL)); uint64_t adjusted_time;
try { adjusted_time = get_daemon_adjusted_time(); }
catch(...) { adjusted_time = time(NULL); } // use local time if no daemon to report blockchain time
// XXX: this needs to be fast, so we'd need to get the starting heights // XXX: this needs to be fast, so we'd need to get the starting heights
// from the daemon to be correct once voting kicks in // from the daemon to be correct once voting kicks in
uint64_t v2height = m_nettype == TESTNET ? 624634 : m_nettype == STAGENET ? 32000 : 1009827; uint64_t v2height = m_nettype == TESTNET ? 624634 : m_nettype == STAGENET ? 32000 : 1009827;
uint64_t leeway = block_height < v2height ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2; uint64_t leeway = block_height < v2height ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2;
if(current_time + leeway >= unlock_time) if(adjusted_time + leeway >= unlock_time)
return true; return true;
else else
return false; return false;
@ -9109,7 +9111,7 @@ void wallet2::transfer_selected_rct(std::vector<cryptonote::tx_destination_entry
LOG_PRINT_L2("transfer_selected_rct done"); LOG_PRINT_L2("transfer_selected_rct done");
} }
std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices) const std::vector<size_t> wallet2::pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices)
{ {
std::vector<size_t> picks; std::vector<size_t> picks;
float current_output_relatdness = 1.0f; float current_output_relatdness = 1.0f;
@ -10780,7 +10782,7 @@ uint64_t wallet2::get_upper_transaction_weight_limit()
return full_reward_zone - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; return full_reward_zone - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
} }
//---------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------
std::vector<size_t> wallet2::select_available_outputs(const std::function<bool(const transfer_details &td)> &f) const std::vector<size_t> wallet2::select_available_outputs(const std::function<bool(const transfer_details &td)> &f)
{ {
std::vector<size_t> outputs; std::vector<size_t> outputs;
size_t n = 0; size_t n = 0;
@ -12085,6 +12087,15 @@ uint64_t wallet2::get_daemon_blockchain_height(string &err)
return height; return height;
} }
uint64_t wallet2::get_daemon_adjusted_time()
{
uint64_t adjusted_time;
boost::optional<std::string> result = m_node_rpc_proxy.get_adjusted_time(adjusted_time);
THROW_WALLET_EXCEPTION_IF(result, error::wallet_internal_error, "Invalid adjusted time from daemon");
return adjusted_time;
}
uint64_t wallet2::get_daemon_blockchain_target_height(string &err) uint64_t wallet2::get_daemon_blockchain_target_height(string &err)
{ {
err = ""; err = "";

View file

@ -939,13 +939,13 @@ private:
// locked & unlocked balance of given or current subaddress account // locked & unlocked balance of given or current subaddress account
uint64_t balance(uint32_t subaddr_index_major, bool strict) const; uint64_t balance(uint32_t subaddr_index_major, bool strict) const;
uint64_t unlocked_balance(uint32_t subaddr_index_major, bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL) const; uint64_t unlocked_balance(uint32_t subaddr_index_major, bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL);
// locked & unlocked balance per subaddress of given or current subaddress account // locked & unlocked balance per subaddress of given or current subaddress account
std::map<uint32_t, uint64_t> balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const; std::map<uint32_t, uint64_t> balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const;
std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict) const; std::map<uint32_t, std::pair<uint64_t, std::pair<uint64_t, uint64_t>>> unlocked_balance_per_subaddress(uint32_t subaddr_index_major, bool strict);
// all locked & unlocked balances of all subaddress accounts // all locked & unlocked balances of all subaddress accounts
uint64_t balance_all(bool strict) const; uint64_t balance_all(bool strict) const;
uint64_t unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL) const; uint64_t unlocked_balance_all(bool strict, uint64_t *blocks_to_unlock = NULL, uint64_t *time_to_unlock = NULL);
template<typename T> template<typename T>
void transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count, void transfer_selected(const std::vector<cryptonote::tx_destination_entry>& dsts, const std::vector<size_t>& selected_transfers, size_t fake_outputs_count,
std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs, std::vector<std::vector<tools::wallet2::get_outs_entry>> &outs,
@ -1003,8 +1003,8 @@ private:
uint64_t get_blockchain_current_height() const { return m_light_wallet_blockchain_height ? m_light_wallet_blockchain_height : m_blockchain.size(); } uint64_t get_blockchain_current_height() const { return m_light_wallet_blockchain_height ? m_light_wallet_blockchain_height : m_blockchain.size(); }
void rescan_spent(); void rescan_spent();
void rescan_blockchain(bool hard, bool refresh = true, bool keep_key_images = false); void rescan_blockchain(bool hard, bool refresh = true, bool keep_key_images = false);
bool is_transfer_unlocked(const transfer_details& td) const; bool is_transfer_unlocked(const transfer_details& td);
bool is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height) const; bool is_transfer_unlocked(uint64_t unlock_time, uint64_t block_height);
uint64_t get_last_block_reward() const { return m_last_block_reward; } uint64_t get_last_block_reward() const { return m_last_block_reward; }
uint64_t get_device_last_key_image_sync() const { return m_device_last_key_image_sync; } uint64_t get_device_last_key_image_sync() const { return m_device_last_key_image_sync; }
@ -1301,13 +1301,15 @@ private:
const boost::optional<epee::net_utils::http::login>& get_daemon_login() const { return m_daemon_login; } const boost::optional<epee::net_utils::http::login>& get_daemon_login() const { return m_daemon_login; }
uint64_t get_daemon_blockchain_height(std::string& err); uint64_t get_daemon_blockchain_height(std::string& err);
uint64_t get_daemon_blockchain_target_height(std::string& err); uint64_t get_daemon_blockchain_target_height(std::string& err);
uint64_t get_daemon_adjusted_time();
/*! /*!
* \brief Calculates the approximate blockchain height from current date/time. * \brief Calculates the approximate blockchain height from current date/time.
*/ */
uint64_t get_approximate_blockchain_height() const; uint64_t get_approximate_blockchain_height() const;
uint64_t estimate_blockchain_height(); uint64_t estimate_blockchain_height();
std::vector<size_t> select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct); std::vector<size_t> select_available_outputs_from_histogram(uint64_t count, bool atleast, bool unlocked, bool allow_rct);
std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f) const; std::vector<size_t> select_available_outputs(const std::function<bool(const transfer_details &td)> &f);
std::vector<size_t> select_available_unmixable_outputs(); std::vector<size_t> select_available_unmixable_outputs();
std::vector<size_t> select_available_mixable_outputs(); std::vector<size_t> select_available_mixable_outputs();
@ -1536,7 +1538,7 @@ private:
void set_tx_notify(const std::shared_ptr<tools::Notify> &notify) { m_tx_notify = notify; } void set_tx_notify(const std::shared_ptr<tools::Notify> &notify) { m_tx_notify = notify; }
bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height) const; bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height);
void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const; void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const;
uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const; uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const;
void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash); void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash);
@ -1600,7 +1602,7 @@ private:
std::vector<uint64_t> get_unspent_amounts_vector(bool strict); std::vector<uint64_t> get_unspent_amounts_vector(bool strict);
uint64_t get_dynamic_base_fee_estimate(); uint64_t get_dynamic_base_fee_estimate();
float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const; float get_output_relatedness(const transfer_details &td0, const transfer_details &td1) const;
std::vector<size_t> pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices) const; std::vector<size_t> pick_preferred_rct_inputs(uint64_t needed_money, uint32_t subaddr_account, const std::set<uint32_t> &subaddr_indices);
void set_spent(size_t idx, uint64_t height); void set_spent(size_t idx, uint64_t height);
void set_unspent(size_t idx); void set_unspent(size_t idx);
bool is_spent(const transfer_details &td, bool strict = true) const; bool is_spent(const transfer_details &td, bool strict = true) const;