|
|
|
@ -1545,6 +1545,42 @@ void wallet2::check_genesis(const crypto::hash& genesis_hash) const {
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
void wallet2::store()
|
|
|
|
|
{
|
|
|
|
|
store_to("", "");
|
|
|
|
|
}
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
void wallet2::store_to(const std::string &path, const std::string &password)
|
|
|
|
|
{
|
|
|
|
|
// if file is the same, we do:
|
|
|
|
|
// 1. save wallet to the *.new file
|
|
|
|
|
// 2. remove old wallet file
|
|
|
|
|
// 3. rename *.new to wallet_name
|
|
|
|
|
|
|
|
|
|
// handle if we want just store wallet state to current files (ex store() replacement);
|
|
|
|
|
bool same_file = true;
|
|
|
|
|
if (!path.empty())
|
|
|
|
|
{
|
|
|
|
|
std::string canonical_path = boost::filesystem::canonical(m_wallet_file).string();
|
|
|
|
|
size_t pos = canonical_path.find(path);
|
|
|
|
|
same_file = pos != std::string::npos;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!same_file)
|
|
|
|
|
{
|
|
|
|
|
// check if we want to store to directory which doesn't exists yet
|
|
|
|
|
boost::filesystem::path parent_path = boost::filesystem::path(path).parent_path();
|
|
|
|
|
|
|
|
|
|
// if path is not exists, try to create it
|
|
|
|
|
if (!parent_path.empty() && !boost::filesystem::exists(parent_path))
|
|
|
|
|
{
|
|
|
|
|
boost::system::error_code ec;
|
|
|
|
|
if (!boost::filesystem::create_directories(parent_path, ec))
|
|
|
|
|
{
|
|
|
|
|
throw std::logic_error(ec.message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// preparing wallet data
|
|
|
|
|
std::stringstream oss;
|
|
|
|
|
boost::archive::binary_oarchive ar(oss);
|
|
|
|
|
ar << *this;
|
|
|
|
@ -1559,10 +1595,10 @@ void wallet2::store()
|
|
|
|
|
crypto::chacha8(cache_file_data.cache_data.data(), cache_file_data.cache_data.size(), key, cache_file_data.iv, &cipher[0]);
|
|
|
|
|
cache_file_data.cache_data = cipher;
|
|
|
|
|
|
|
|
|
|
// save to new file, rename main to old, rename new to main
|
|
|
|
|
// at all times, there should be a valid file on disk
|
|
|
|
|
const std::string new_file = m_wallet_file + ".new";
|
|
|
|
|
const std::string old_file = m_wallet_file + ".old";
|
|
|
|
|
const std::string new_file = same_file ? m_wallet_file + ".new" : path;
|
|
|
|
|
const std::string old_file = m_wallet_file;
|
|
|
|
|
const std::string old_keys_file = m_keys_file;
|
|
|
|
|
const std::string old_address_file = m_wallet_file + ".address.txt";
|
|
|
|
|
|
|
|
|
|
// save to new file
|
|
|
|
|
std::ofstream ostr;
|
|
|
|
@ -1572,87 +1608,35 @@ void wallet2::store()
|
|
|
|
|
ostr.close();
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!success || !ostr.good(), error::file_save_error, new_file);
|
|
|
|
|
|
|
|
|
|
// rename
|
|
|
|
|
boost::filesystem::remove(old_file); // probably does not exist
|
|
|
|
|
if (boost::filesystem::exists(m_wallet_file)) {
|
|
|
|
|
std::error_code e = tools::replace_file(m_wallet_file, old_file);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(e, error::file_save_error, m_wallet_file, e);
|
|
|
|
|
}
|
|
|
|
|
std::error_code e = tools::replace_file(new_file, m_wallet_file);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(e, error::file_save_error, m_wallet_file, e);
|
|
|
|
|
boost::filesystem::remove(old_file);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void wallet2::store_to(const std::string &path, const std::string &password)
|
|
|
|
|
{
|
|
|
|
|
// TODO: merge it with wallet2::store() function
|
|
|
|
|
|
|
|
|
|
// check if we want to store to directory which doesn't exists yet
|
|
|
|
|
boost::filesystem::path parent_path = boost::filesystem::path(path).parent_path();
|
|
|
|
|
|
|
|
|
|
// if path is not exists, try to create it
|
|
|
|
|
if (!parent_path.empty() && !boost::filesystem::exists(parent_path)) {
|
|
|
|
|
boost::system::error_code ec;
|
|
|
|
|
if (!boost::filesystem::create_directories(parent_path, ec)) {
|
|
|
|
|
throw std::logic_error(ec.message());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::stringstream oss;
|
|
|
|
|
boost::archive::binary_oarchive ar(oss);
|
|
|
|
|
ar << *this;
|
|
|
|
|
|
|
|
|
|
wallet2::cache_file_data cache_file_data = boost::value_initialized<wallet2::cache_file_data>();
|
|
|
|
|
cache_file_data.cache_data = oss.str();
|
|
|
|
|
crypto::chacha8_key key;
|
|
|
|
|
generate_chacha8_key_from_secret_keys(key);
|
|
|
|
|
std::string cipher;
|
|
|
|
|
cipher.resize(cache_file_data.cache_data.size());
|
|
|
|
|
cache_file_data.iv = crypto::rand<crypto::chacha8_iv>();
|
|
|
|
|
crypto::chacha8(cache_file_data.cache_data.data(), cache_file_data.cache_data.size(), key, cache_file_data.iv, &cipher[0]);
|
|
|
|
|
cache_file_data.cache_data = cipher;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const std::string new_file = path;
|
|
|
|
|
const std::string old_file = m_wallet_file;
|
|
|
|
|
const std::string old_keys_file = m_keys_file;
|
|
|
|
|
const std::string old_address_file = m_wallet_file + ".address.txt";
|
|
|
|
|
|
|
|
|
|
// save to new file
|
|
|
|
|
std::ofstream ostr;
|
|
|
|
|
ostr.open(new_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
|
|
|
|
|
binary_archive<true> oar(ostr);
|
|
|
|
|
bool success = ::serialization::serialize(oar, cache_file_data);
|
|
|
|
|
ostr.close();
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!success || !ostr.good(), error::file_save_error, new_file);
|
|
|
|
|
|
|
|
|
|
// save keys to the new file
|
|
|
|
|
// if we here, main wallet file is saved and we only need to save keys and address files
|
|
|
|
|
// save keys to the new file
|
|
|
|
|
// if we here, main wallet file is saved and we only need to save keys and address files
|
|
|
|
|
if (!same_file) {
|
|
|
|
|
prepare_file_names(path);
|
|
|
|
|
store_keys(m_keys_file, password, false);
|
|
|
|
|
|
|
|
|
|
// save address to the new file
|
|
|
|
|
const std::string address_file = m_wallet_file + ".address.txt";
|
|
|
|
|
bool r = file_io_utils::save_string_to_file(address_file, m_account.get_public_address_str(m_testnet));
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// remove old wallet file
|
|
|
|
|
r = boost::filesystem::remove(old_file);
|
|
|
|
|
if (!r) {
|
|
|
|
|
LOG_ERROR("error removing file: " << old_file);
|
|
|
|
|
LOG_ERROR("error removing file: " << old_file);
|
|
|
|
|
}
|
|
|
|
|
// remove old keys file
|
|
|
|
|
r = boost::filesystem::remove(old_keys_file);
|
|
|
|
|
if (!r) {
|
|
|
|
|
LOG_ERROR("error removing file: " << old_keys_file);
|
|
|
|
|
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);
|
|
|
|
|
LOG_ERROR("error removing file: " << old_address_file);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// here we have "*.new" file, we need to rename it to be without ".new"
|
|
|
|
|
std::error_code e = tools::replace_file(new_file, m_wallet_file);
|
|
|
|
|
THROW_WALLET_EXCEPTION_IF(e, error::file_save_error, m_wallet_file, e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//----------------------------------------------------------------------------------------------------
|
|
|
|
|
uint64_t wallet2::unlocked_balance() const
|
|
|
|
@ -3072,12 +3056,12 @@ bool wallet2::get_tx_key(const crypto::hash &txid, crypto::secret_key &tx_key) c
|
|
|
|
|
|
|
|
|
|
std::string wallet2::get_wallet_file() const
|
|
|
|
|
{
|
|
|
|
|
return m_wallet_file;
|
|
|
|
|
return m_wallet_file;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::string wallet2::get_keys_file() const
|
|
|
|
|
{
|
|
|
|
|
return m_keys_file;
|
|
|
|
|
return m_keys_file;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void wallet2::set_tx_note(const crypto::hash &txid, const std::string ¬e)
|
|
|
|
|