mirror of
https://github.com/monero-project/monero.git
synced 2024-11-17 16:27:39 +00:00
wallet2::store() implemented within wallet2::store_to
This commit is contained in:
parent
7df2baf6b0
commit
2cce32995b
4 changed files with 87 additions and 69 deletions
|
@ -1424,6 +1424,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;
|
||||
|
@ -1438,10 +1474,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;
|
||||
|
@ -1451,87 +1487,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
|
||||
|
@ -2769,12 +2753,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;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
|
@ -276,6 +276,7 @@ public:
|
|||
virtual bool closeWallet(Wallet *wallet);
|
||||
bool walletExists(const std::string &path);
|
||||
std::string errorString() const;
|
||||
void setDaemonHost(const std::string &hostname);
|
||||
|
||||
|
||||
private:
|
||||
|
@ -329,6 +330,11 @@ std::string WalletManagerImpl::errorString() const
|
|||
return m_errorString;
|
||||
}
|
||||
|
||||
void WalletManagerImpl::setDaemonHost(const std::string &hostname)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////// WalletManagerFactory implementation //////////////////////
|
||||
|
|
|
@ -112,6 +112,9 @@ struct WalletManager
|
|||
|
||||
virtual std::string errorString() const = 0;
|
||||
|
||||
virtual void setDaemonHost(const std::string &hostname) = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -165,6 +165,7 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet1)
|
|||
ASSERT_TRUE(wmgr->closeWallet(wallet2));
|
||||
}
|
||||
|
||||
|
||||
TEST_F(WalletManagerTest, WalletManagerStoresWallet2)
|
||||
{
|
||||
Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG);
|
||||
|
@ -181,6 +182,7 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet2)
|
|||
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
||||
}
|
||||
|
||||
|
||||
TEST_F(WalletManagerTest, WalletManagerStoresWallet3)
|
||||
{
|
||||
Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG);
|
||||
|
@ -204,6 +206,29 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet3)
|
|||
}
|
||||
|
||||
|
||||
TEST_F(WalletManagerTest, WalletManagerStoresWallet4)
|
||||
{
|
||||
Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG);
|
||||
std::string seed1 = wallet1->seed();
|
||||
std::string address1 = wallet1->address();
|
||||
|
||||
ASSERT_TRUE(wallet1->store(""));
|
||||
ASSERT_TRUE(wallet1->status() == Bitmonero::Wallet::Status_Ok);
|
||||
|
||||
ASSERT_TRUE(wallet1->store(""));
|
||||
ASSERT_TRUE(wallet1->status() == Bitmonero::Wallet::Status_Ok);
|
||||
|
||||
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
||||
|
||||
wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS);
|
||||
ASSERT_TRUE(wallet1->status() == Bitmonero::Wallet::Status_Ok);
|
||||
ASSERT_TRUE(wallet1->seed() == seed1);
|
||||
ASSERT_TRUE(wallet1->address() == address1);
|
||||
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
//epee::debug::get_set_enable_assert(true, false);
|
||||
|
|
Loading…
Reference in a new issue