forked from lthn/blockchain
wallet2: restore_key_images_in_wo_wallet() implemented
This commit is contained in:
parent
2f368cbf2c
commit
c241cb3f9b
3 changed files with 108 additions and 2 deletions
|
|
@ -302,10 +302,11 @@ namespace crypto {
|
|||
} // namespace crypto
|
||||
|
||||
POD_MAKE_HASHABLE(crypto, public_key)
|
||||
POD_MAKE_LESS_OPERATOR(crypto, public_key)
|
||||
POD_MAKE_COMPARABLE(crypto, secret_key)
|
||||
POD_MAKE_HASHABLE(crypto, key_image)
|
||||
POD_MAKE_COMPARABLE(crypto, signature)
|
||||
POD_MAKE_COMPARABLE(crypto, key_derivation)
|
||||
POD_MAKE_LESS_OPERATOR(crypto, hash)
|
||||
POD_MAKE_LESS_OPERATOR(crypto, key_image)
|
||||
POP_GCC_WARNINGS
|
||||
POP_GCC_WARNINGS
|
||||
|
|
|
|||
|
|
@ -92,6 +92,11 @@ namespace tools
|
|||
m_core_runtime_config = currency::get_default_core_runtime_config();
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
wallet2::~wallet2()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
uint64_t wallet2::get_max_unlock_time_from_receive_indices(const currency::transaction& tx, const wallet_public::employed_tx_entries& td)
|
||||
{
|
||||
uint64_t max_unlock_time = 0;
|
||||
|
|
@ -5231,7 +5236,11 @@ bool wallet2::reset_history()
|
|||
std::wstring file_path = m_wallet_file;
|
||||
account_base acc_tmp = m_account;
|
||||
auto tx_keys = m_tx_keys;
|
||||
auto pending_key_images = m_pending_key_images;
|
||||
crypto::hash genesis_id = m_chain.get_genesis();
|
||||
clear();
|
||||
m_chain.set_genesis(genesis_id);
|
||||
m_pending_key_images = pending_key_images;
|
||||
m_tx_keys = tx_keys;
|
||||
m_account = acc_tmp;
|
||||
m_password = pass;
|
||||
|
|
@ -7858,6 +7867,100 @@ bool wallet2::is_need_to_split_outputs()
|
|||
return !is_in_hardfork_zone(ZANO_HARDFORK_04_ZARCANUM);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::restore_key_images_in_wo_wallet(const std::wstring& filename, const std::string& password) const
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(!m_watch_only, "restore_key_images_in_wo_wallet can only be used in non watch-only wallet");
|
||||
bool r = false;
|
||||
|
||||
// load the given watch-only wallet
|
||||
wallet2 wo;
|
||||
wo.load(filename, password);
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(wo.is_watch_only(), epee::string_encoding::wstring_to_utf8(filename) << " is not a watch-only wallet");
|
||||
if (m_account.get_keys().view_secret_key != wo.get_account().get_keys().view_secret_key ||
|
||||
m_account.get_public_address() != wo.get_account().get_public_address())
|
||||
{
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(false, epee::string_encoding::wstring_to_utf8(filename) << " has keys that differ from this wallet's keys; wrong wallet?");
|
||||
}
|
||||
|
||||
//
|
||||
// 1. Find missing key images and calculate them using secret spend key. Populate missing_ki_items container.
|
||||
//
|
||||
struct missing_ki_item
|
||||
{
|
||||
crypto::public_key tx_pub_key;
|
||||
crypto::public_key out_pub_key;
|
||||
uint64_t output_index;
|
||||
uint64_t transfer_index;
|
||||
crypto::key_image ki;
|
||||
};
|
||||
|
||||
std::set<size_t> transfer_indices_to_include;
|
||||
for(auto el : wo.m_pending_key_images)
|
||||
{
|
||||
const crypto::key_image& ki = el.second;
|
||||
auto it = wo.m_key_images.find(ki);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(it != wo.m_key_images.end(), "restore_key_images_in_wo_wallet: m_key_images inconsistency, ki: " << ki);
|
||||
size_t transfer_index = it->second;
|
||||
transfer_indices_to_include.insert(transfer_index);
|
||||
WLT_LOG_L1("restore_key_images_in_wo_wallet: transfer " << transfer_index << " is in m_pending_key_images, included");
|
||||
}
|
||||
|
||||
for(auto el : wo.m_transfers)
|
||||
{
|
||||
size_t transfer_index = el.first;
|
||||
if (el.second.m_key_image == null_ki)
|
||||
{
|
||||
transfer_indices_to_include.insert(transfer_index);
|
||||
WLT_LOG_L1("restore_key_images_in_wo_wallet: ki is null for ti " << transfer_index << ", included");
|
||||
}
|
||||
}
|
||||
|
||||
// now in transfer_indices_to_include we have ordered and unique list of transfer indices
|
||||
std::vector<missing_ki_item> missing_ki_items;
|
||||
std::set<crypto::public_key> pk_uniqueness_set;
|
||||
for(size_t transfer_index : transfer_indices_to_include)
|
||||
{
|
||||
const auto& td = wo.m_transfers.at(transfer_index);
|
||||
auto& item = missing_ki_items.emplace_back();
|
||||
item.output_index = td.m_internal_output_index;
|
||||
crypto::public_key out_pub_key{};
|
||||
r = get_out_pub_key_from_tx_out_v(td.output(), out_pub_key);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "restore_key_images_in_wo_wallet failed for ti: " << transfer_index);
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(pk_uniqueness_set.insert(out_pub_key).second, "restore_key_images_in_wo_wallet: out pub key in not unique: " << out_pub_key << ", ti: " << transfer_index);
|
||||
item.out_pub_key = out_pub_key;
|
||||
item.transfer_index = transfer_index;
|
||||
item.tx_pub_key = get_tx_pub_key_from_extra(td.m_ptx_wallet_info->m_tx);
|
||||
WLT_LOG_L0("restore_key_images_in_wo_wallet: including: " << item.out_pub_key << ", " << transfer_index);
|
||||
|
||||
// calculate key image
|
||||
keypair ephemeral{};
|
||||
generate_key_image_helper(m_account.get_keys(), item.tx_pub_key, item.output_index, ephemeral, item.ki);
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(ephemeral.pub == item.out_pub_key, "restore_key_images_in_wo_wallet: out pub key missmatch, ti: " << transfer_index);
|
||||
};
|
||||
|
||||
//
|
||||
// 2. Actually restore key images in the 'wo' object.
|
||||
//
|
||||
r = wo.m_pending_key_images_file_container.clear();
|
||||
WLT_THROW_IF_FALSE_WALLET_CMN_ERR_EX(r, "restore_key_images_in_wo_wallet: pending ki container clearing failed");
|
||||
wo.m_pending_key_images.clear();
|
||||
|
||||
for(size_t i = 0; i < missing_ki_items.size(); ++i)
|
||||
{
|
||||
const auto& item = missing_ki_items[i];
|
||||
auto& td = wo.m_transfers[item.transfer_index]; // item.transfer_index validity was checked above
|
||||
|
||||
td.m_key_image = item.ki; // TODO: it's unclear whether we need to update m_transfers[].m_key_image since later I decided to clear history to trigger resync later. Probably, no. -- sowle
|
||||
r = wo.m_pending_key_images.insert(std::make_pair(item.out_pub_key, item.ki)).second;
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(r, "restore_key_images_in_wo_wallet: insert failed, out_pub_key: " << item.out_pub_key << ", i: " << i);
|
||||
wo.m_pending_key_images_file_container.push_back(out_key_to_ki{item.out_pub_key, item.ki});
|
||||
LOG_PRINT_L0("restore_key_images_in_wo_wallet: added #" << i << " ti: " << item.transfer_index << ", pk: " << item.out_pub_key << ", ki: " << item.ki);
|
||||
}
|
||||
|
||||
wo.reset_history();
|
||||
wo.store();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::prepare_tx_destinations(const assets_selection_context& needed_money_map,
|
||||
detail::split_strategy_id_t destination_split_strategy_id,
|
||||
const tx_dust_policy& dust_policy,
|
||||
|
|
|
|||
|
|
@ -262,7 +262,7 @@ namespace tools
|
|||
wallet2(const wallet2&) = delete;
|
||||
public:
|
||||
wallet2();
|
||||
virtual ~wallet2() {}
|
||||
virtual ~wallet2();
|
||||
|
||||
static std::string transfer_flags_to_str(uint32_t flags);
|
||||
|
||||
|
|
@ -617,6 +617,8 @@ namespace tools
|
|||
void submit_transfer_files(const std::string& signed_tx_file, currency::transaction& tx);
|
||||
void submit_externally_signed_asset_tx(const currency::finalized_tx& ft, const crypto::generic_schnorr_sig_s& gss_sig, bool unlock_transfers_on_fail, currency::transaction& result_tx, bool& transfers_unlocked);
|
||||
void submit_externally_signed_asset_tx(const currency::finalized_tx& ft, const crypto::eth_signature& eth_sig, bool unlock_transfers_on_fail, currency::transaction& result_tx, bool& transfers_unlocked);
|
||||
|
||||
void restore_key_images_in_wo_wallet(const std::wstring& filename, const std::string& password) const;
|
||||
|
||||
void sweep_below(size_t fake_outs_count, const currency::account_public_address& destination_addr, uint64_t threshold_amount, const currency::payment_id_t& payment_id,
|
||||
uint64_t fee, size_t& outs_total, uint64_t& amount_total, size_t& outs_swept, uint64_t& amount_swept, currency::transaction* p_result_tx = nullptr, std::string* p_filename_or_unsigned_tx_blob_str = nullptr);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue