add return into type to wallet serialization (#42)

This commit is contained in:
akildemir
2025-08-06 17:00:56 +03:00
committed by GitHub
parent 92812621be
commit 906e55f87b
5 changed files with 87 additions and 31 deletions
+51
View File
@@ -52,6 +52,16 @@ namespace carrot
crypto::secret_key x;
crypto::secret_key y;
return_output_info_t() {
// Default constructor for serialization
input_context = input_context_t();
K_o = crypto::public_key();
K_change = crypto::public_key();
key_image = crypto::key_image();
x = crypto::secret_key();
y = crypto::secret_key();
}
return_output_info_t(
const input_context_t &input_context,
const crypto::public_key &K_o,
@@ -65,6 +75,15 @@ namespace carrot
key_image(key_image),
x(x),
y(y) {}
BEGIN_SERIALIZE_OBJECT()
FIELD(input_context)
FIELD(K_o)
FIELD(K_change)
FIELD(key_image)
FIELD(x)
FIELD(y)
END_SERIALIZE()
};
@@ -148,3 +167,35 @@ namespace carrot
std::unordered_map<crypto::public_key, return_output_info_t> return_output_map;
};
}
namespace boost
{
namespace serialization
{
template <class Archive>
inline typename std::enable_if<!Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, carrot::return_output_info_t &x, const boost::serialization::version_type ver)
{
}
template <class Archive>
inline typename std::enable_if<Archive::is_loading::value, void>::type initialize_transfer_details(Archive &a, carrot::return_output_info_t &x, const boost::serialization::version_type ver)
{
x.input_context = carrot::input_context_t();
x.K_o = crypto::public_key();
x.K_change = crypto::public_key();
x.key_image = crypto::key_image();
x.x = crypto::secret_key();
x.y = crypto::secret_key();
}
template <class Archive>
inline void serialize(Archive &a, carrot::return_output_info_t &x, const boost::serialization::version_type ver)
{
a & x.input_context;
a & x.K_o;
a & x.K_change;
a & x.key_image;
a & x.x;
a & x.y;
}
}
}
@@ -73,6 +73,11 @@ namespace boost
a & reinterpret_cast<char (&)[sizeof(crypto::key_image)]>(x);
}
template <class Archive>
inline void serialize(Archive &a, carrot::input_context_t &x, const boost::serialization::version_type ver)
{
a & reinterpret_cast<char (&)[sizeof(carrot::input_context_t)]>(x);
}
template <class Archive>
inline void serialize(Archive &a, crypto::view_tag &x, const boost::serialization::version_type ver)
{
a & reinterpret_cast<char (&)[sizeof(crypto::view_tag)]>(x);
+3
View File
@@ -38,6 +38,7 @@
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "mx25519.h"
#include "carrot_core/core_types.h"
// read
template <template <bool> class Archive>
@@ -85,6 +86,7 @@ BLOB_SERIALIZER(crypto::public_key);
BLOB_SERIALIZER(crypto::secret_key);
BLOB_SERIALIZER(crypto::key_derivation);
BLOB_SERIALIZER(crypto::key_image);
BLOB_SERIALIZER(carrot::input_context_t);
BLOB_SERIALIZER(crypto::signature);
BLOB_SERIALIZER(crypto::view_tag);
BLOB_SERIALIZER(crypto::ec_point);
@@ -95,6 +97,7 @@ VARIANT_TAG(debug_archive, crypto::public_key, "public_key");
VARIANT_TAG(debug_archive, crypto::secret_key, "secret_key");
VARIANT_TAG(debug_archive, crypto::key_derivation, "key_derivation");
VARIANT_TAG(debug_archive, crypto::key_image, "key_image");
VARIANT_TAG(debug_archive, carrot::input_context_t, "input_context");
VARIANT_TAG(debug_archive, crypto::signature, "signature");
VARIANT_TAG(debug_archive, crypto::view_tag, "view_tag");
VARIANT_TAG(debug_archive, crypto::ec_point, "ec_point");
+25 -31
View File
@@ -2849,21 +2849,8 @@ void wallet2::process_new_scanned_transaction(
// save the change output key in our subaddress_map, so we can receive money to it later
// from protocol or return txs
for (const auto &entry: tx_amounts_individual_outs[i->first]) {
const crypto::public_key &onetime_address = std::get<1>(entry);
carrot::AddressDeriveType derive_type;
if (use_fork_rules(HF_VERSION_CARROT, 0)) {
derive_type = carrot::AddressDeriveType::Carrot;
} else {
derive_type = carrot::AddressDeriveType::PreCarrot;
}
const carrot::subaddress_index_extended subaddr_ext = {i->first.major, i->first.minor, derive_type, true};
// save to m_subaddresses as well, so that we can populate account subaddress map
// when we open the wallet first time.
if (derive_type == carrot::AddressDeriveType::PreCarrot)
m_subaddresses_extended[onetime_address] = subaddr_ext;
// update m_salvium_txs
m_salvium_txs.insert({onetime_address, m_transfers.size()-1});
m_salvium_txs.insert({std::get<1>(entry), m_transfers.size()-1});
}
// delete change output from amounts
@@ -3113,8 +3100,7 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b,
m_last_block_reward = cryptonote::get_outs_money_amount(b.miner_tx);
LOG_PRINT_L2("Processed block: " << bl_id << ", height " << height << ", " << miner_tx_handle_time + txs_handle_time << "(" << miner_tx_handle_time << "/" << txs_handle_time <<")ms");
}else
{
} else {
if (!(height % 128))
LOG_PRINT_L2( "Skipped block by timestamp, height: " << height << ", block time " << b.timestamp << ", account time " << m_account.get_createtime());
}
@@ -3382,19 +3368,6 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
size_t i = 0;
size_t tx_output_idx = 0;
while (i < blocks.size()) {
/*
if (!skip_scan_for_this_block && m_refresh_type != RefreshNoCoinbase)
tx_scan_job(par_blk.block.miner_tx, tx_output_idx);
tx_output_idx += par_blk.block.miner_tx.vout.size();
if (!skip_scan_for_this_block && m_refresh_type != RefreshNoCoinbase)
tx_scan_job(par_blk.block.protocol_tx, tx_output_idx);
tx_output_idx += par_blk.block.protocol_tx.vout.size();
for (const cryptonote::transaction &tx : par_blk.txes)
{
if (!skip_scan_for_this_block)
tx_scan_job(tx, tx_output_idx);
tx_output_idx += tx.vout.size();
*/
tools::threadpool::waiter scan_blocks_waiter(tpool);
for (size_t j = 0; j < 10; ++j)
{
@@ -3468,6 +3441,23 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect
tx_output_idx += n_block_outputs;
++current_index;
}
// save accumulated return subaddresses to m_subaddresses_extended, so that we can re-insert
// them into account after we restart the wallet.
m_subaddresses_extended.clear();
for (const auto& subaddr: m_account.get_subaddress_map_ref()) {
if (subaddr.second.derive_type == carrot::AddressDeriveType::PreCarrot &&
subaddr.second.is_return_spend_key == true
) {
m_subaddresses_extended.insert({subaddr.first, subaddr.second});
}
}
// save accumulated return output info to wallet
m_return_output_info.clear();
for (const auto& output_info: m_account.get_return_output_map_ref()) {
m_return_output_info.insert({output_info.first, output_info.second});
}
}
//----------------------------------------------------------------------------------------------------
void wallet2::refresh(bool trusted_daemon)
@@ -6596,17 +6586,21 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass
if (get_num_subaddress_accounts() == 0)
add_subaddress_account(tr("Primary account"));
m_account.insert_subaddresses(m_subaddresses_extended);
// populate account subaddress list
if (!m_subaddresses.empty())
{
// if we have subaddresses, we need to insert them into the account
for (const auto &subaddress : m_subaddresses)
m_account.insert_subaddresses(
// TODO: we assume none of these subaddresses are return tx subaddresses
// we assume none of these subaddresses are return tx subaddresses
{{subaddress.first, {{subaddress.second.major, subaddress.second.minor}, carrot::AddressDeriveType::PreCarrot, false}}}
);
}
m_account.insert_subaddresses(m_subaddresses_extended);
// populate account return output info
m_account.insert_return_output_info(m_return_output_info);
try
{
+3
View File
@@ -1417,6 +1417,7 @@ private:
return;
a & m_subaddresses.parent();
a & m_subaddresses_extended.parent();
a & m_return_output_info.parent();
std::unordered_map<cryptonote::subaddress_index, crypto::public_key> dummy_subaddresses_inv;
a & dummy_subaddresses_inv;
a & m_subaddress_labels;
@@ -1484,6 +1485,7 @@ private:
FIELD(m_scanned_pool_txs[1])
FIELD(m_subaddresses)
FIELD(m_subaddresses_extended)
FIELD(m_return_output_info)
FIELD(m_subaddress_labels)
FIELD(m_additional_tx_keys)
FIELD(m_attributes)
@@ -2147,6 +2149,7 @@ private:
cryptonote::account_public_address m_account_public_address;
serializable_unordered_map<crypto::public_key, cryptonote::subaddress_index> m_subaddresses;
serializable_unordered_map<crypto::public_key, carrot::subaddress_index_extended> m_subaddresses_extended;
serializable_unordered_map<crypto::public_key, carrot::return_output_info_t> m_return_output_info;
std::vector<std::vector<std::string>> m_subaddress_labels;
serializable_unordered_map<crypto::hash, std::string> m_tx_notes;
serializable_unordered_map<std::string, std::string> m_attributes;