Display checkpointedness of transactions in wallet

This commit is contained in:
Doyle 2019-10-02 17:44:22 +10:00
parent 918a92c8fa
commit dded026a3a
6 changed files with 41 additions and 6 deletions

View file

@ -7946,12 +7946,13 @@ bool simple_wallet::show_transfers(const std::vector<std::string> &args_)
}
}
auto formatter = boost::format("%8.8llu %6.6s %8.8s %16.16s %20.20s %s %s %14.14s %s %s - %s");
auto formatter = boost::format("%8.8llu %6.6s %8.8s %12.12s %16.16s %20.20s %s %s %14.14s %s %s - %s");
message_writer(color, false) << formatter
% transfer.block
% tools::pay_type_string(transfer.type)
% transfer.lock_msg
% (transfer.checkpointed ? "checkpointed" : "no")
% tools::get_human_readable_timestamp(transfer.timestamp)
% print_money(transfer.amount)
% string_tools::pod_to_hex(transfer.hash)
@ -9265,6 +9266,7 @@ bool simple_wallet::show_transfer(const std::vector<std::string> &args)
else
success_msg_writer() << "locked for " << tools::get_human_readable_timespan(std::chrono::seconds(pd.m_unlock_time - threshold));
}
success_msg_writer() << "Checkpointed: " << (pd.m_block_height <= m_wallet->get_immutable_height() ? "Yes" : "No");
success_msg_writer() << "Address index: " << pd.m_subaddr_index.minor;
success_msg_writer() << "Note: " << m_wallet->get_tx_note(txid);
return true;

View file

@ -58,6 +58,7 @@ void NodeRPCProxy::invalidate()
m_contributed_service_nodes.clear();
m_height = 0;
m_immutable_height = 0;
for (size_t n = 0; n < 256; ++n)
m_earliest_height[n] = 0;
m_dynamic_base_fee_estimate = {0, 0};
@ -93,6 +94,8 @@ boost::optional<std::string> NodeRPCProxy::get_rpc_version(uint32_t &rpc_version
void NodeRPCProxy::set_height(uint64_t h)
{
m_height = h;
if (h < m_immutable_height)
m_immutable_height = 0;
}
boost::optional<std::string> NodeRPCProxy::get_info() const
@ -115,6 +118,7 @@ boost::optional<std::string> NodeRPCProxy::get_info() const
m_height = resp_t.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_immutable_height = resp_t.immutable_height;
m_get_info_time = now;
}
return boost::optional<std::string>();
@ -138,6 +142,15 @@ boost::optional<std::string> NodeRPCProxy::get_target_height(uint64_t &height) c
return boost::optional<std::string>();
}
boost::optional<std::string> NodeRPCProxy::get_immutable_height(uint64_t &height) const
{
auto res = get_info();
if (res)
return res;
height = m_immutable_height;
return boost::optional<std::string>();
}
boost::optional<std::string> NodeRPCProxy::get_block_weight_limit(uint64_t &block_weight_limit) const
{
auto res = get_info();

View file

@ -49,6 +49,7 @@ public:
boost::optional<std::string> get_height(uint64_t &height) const;
void set_height(uint64_t h);
boost::optional<std::string> get_target_height(uint64_t &height) const;
boost::optional<std::string> get_immutable_height(uint64_t &height) const;
boost::optional<std::string> get_block_weight_limit(uint64_t &block_weight_limit) const;
boost::optional<std::string> get_earliest_height(uint8_t version, uint64_t &earliest_height) const;
boost::optional<std::string> get_dynamic_base_fee_estimate(uint64_t grace_blocks, cryptonote::byte_and_output_fees &fees) const;
@ -80,6 +81,7 @@ private:
mutable std::vector<cryptonote::COMMAND_RPC_GET_SERVICE_NODES::response::entry> m_contributed_service_nodes;
mutable uint64_t m_height;
mutable uint64_t m_immutable_height;
mutable uint64_t m_earliest_height[256];
mutable cryptonote::byte_and_output_fees m_dynamic_base_fee_estimate;
mutable uint64_t m_dynamic_base_fee_estimate_cached_height;

View file

@ -3293,6 +3293,11 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
if(last_tx_hash_id != (m_transfers.size() ? m_transfers.back().m_txid : null_hash))
received_money = true;
uint64_t immutable_height = 0;
boost::optional<std::string> fail_string = m_node_rpc_proxy.get_immutable_height(immutable_height);
if (!fail_string)
m_immutable_height = immutable_height;
try
{
// If stop() is called we don't need to check pending transactions
@ -5801,6 +5806,7 @@ void wallet2::fill_transfer_view(wallet2::transfer_view &entry, const crypto::ha
const bool unlocked = is_transfer_unlocked(entry.unlock_time, entry.height);
entry.lock_msg = unlocked ? "unlocked" : "locked";
set_confirmations(entry, get_blockchain_current_height(), get_last_block_reward());
entry.checkpointed = entry.height <= m_immutable_height;
}
//------------------------------------------------------------------------------------------------------------------------------
void wallet2::fill_transfer_view(wallet2::transfer_view &entry, const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) const
@ -5832,6 +5838,7 @@ void wallet2::fill_transfer_view(wallet2::transfer_view &entry, const crypto::ha
entry.subaddr_indices.push_back({pd.m_subaddr_account, i});
entry.address = get_subaddress_as_str({pd.m_subaddr_account, 0});
entry.confirmed = true;
entry.checkpointed = entry.height <= m_immutable_height;
set_confirmations(entry, get_blockchain_current_height(), get_last_block_reward());
}
//------------------------------------------------------------------------------------------------------------------------------
@ -5966,12 +5973,12 @@ void wallet2::get_transfers(get_transfers_args_t args, std::vector<transfer_view
std::string wallet2::transfers_to_csv(const std::vector<wallet2::transfer_view>& transfers, bool formatting) const
{
uint64_t running_balance = 0;
auto data_formatter = boost::format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,'%s',%s");
auto title_formatter = boost::format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s");
auto data_formatter = boost::format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,'%s',%s");
auto title_formatter = boost::format("%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s");
if (formatting)
{
title_formatter = boost::format("%8.8s,%9.9s,%8.8s,%16.16s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%100.100s,%20.20s,%s,%s");
data_formatter = boost::format("%8.8s,%9.9s,%8.8s,%16.16s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%100.100s,%20.20s,\"%s\",%s");
title_formatter = boost::format("%8.8s,%9.9s,%8.8s,%14.14s,%16.16s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%100.100s,%20.20s,%s,%s");
data_formatter = boost::format("%8.8s,%9.9s,%8.8s,%14.14s,%16.16s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%100.100s,%20.20s,\"%s\",%s");
}
auto new_line = [&](std::stringstream& output){
@ -5990,6 +5997,7 @@ std::string wallet2::transfers_to_csv(const std::vector<wallet2::transfer_view>&
% tr("block")
% tr("type")
% tr("lock")
% tr("checkpointed")
% tr("timestamp")
% tr("amount")
% tr("running balance")
@ -6027,6 +6035,7 @@ std::string wallet2::transfers_to_csv(const std::vector<wallet2::transfer_view>&
% transfer.block
% pay_type_string(transfer.type)
% transfer.lock_msg
% (transfer.checkpointed ? "checkpointed" : "no")
% tools::get_human_readable_timestamp(transfer.timestamp)
% cryptonote::print_money(transfer.amount)
% cryptonote::print_money(running_balance)
@ -6056,6 +6065,7 @@ std::string wallet2::transfers_to_csv(const std::vector<wallet2::transfer_view>&
% ""
% ""
% ""
% ""
% it->address
% cryptonote::print_money(it->amount)
% ""

View file

@ -494,6 +494,7 @@ private:
bool double_spend_seen; // True if the key image(s) for the transfer have been seen before.
uint64_t confirmations; // Number of block mined since the block containing this transaction (or block height at which the transaction should be added to a block if not yet confirmed).
uint64_t suggested_confirmations_threshold;
bool checkpointed = false; // If the transfer is backed by atleast (2 service node|| 1 hardcoded) checkpoints // TODO(loki): Make this count the number of checkpoints backing this transfer
};
typedef std::vector<transfer_details> transfer_container;
@ -963,6 +964,7 @@ private:
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_immutable_height() const { return m_immutable_height; }
template <class t_archive>
inline void serialize(t_archive &a, const unsigned int ver)
@ -1077,6 +1079,9 @@ private:
if(ver < 28)
return;
a & m_cold_key_images;
if(ver < 29)
return;
a & m_immutable_height;
}
/*!
@ -1667,6 +1672,7 @@ private:
std::string m_device_derivation_path;
uint64_t m_device_last_key_image_sync;
bool m_offline;
uint64_t m_immutable_height;
// Aux transaction data from device
std::unordered_map<crypto::hash, std::string> m_tx_device;
@ -1721,7 +1727,7 @@ private:
bool parse_priority (const std::string& arg, uint32_t& priority);
}
BOOST_CLASS_VERSION(tools::wallet2, 28)
BOOST_CLASS_VERSION(tools::wallet2, 29)
BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 12)
BOOST_CLASS_VERSION(tools::wallet2::multisig_info, 1)
BOOST_CLASS_VERSION(tools::wallet2::multisig_info::LR, 0)

View file

@ -1499,6 +1499,7 @@ namespace wallet_rpc
bool double_spend_seen; // True if the key image(s) for the transfer have been seen before.
uint64_t confirmations; // Number of block mined since the block containing this transaction (or block height at which the transaction should be added to a block if not yet confirmed).
uint64_t suggested_confirmations_threshold; // Estimation of the confirmations needed for the transaction to be included in a block.
uint64_t checkpointed; // If transfer is backed by atleast 2 Service Node Checkpoints, 0 if it is not, see immutable_height in the daemon rpc call get_info
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(txid);
@ -1517,6 +1518,7 @@ namespace wallet_rpc
KV_SERIALIZE(double_spend_seen)
KV_SERIALIZE_OPT(confirmations, (uint64_t)0)
KV_SERIALIZE_OPT(suggested_confirmations_threshold, (uint64_t)0)
KV_SERIALIZE(checkpointed)
END_KV_SERIALIZE_MAP()
};