wallet2::store() implemented within wallet2::store_to
This commit is contained in:
parent
7df2baf6b0
commit
2cce32995b
|
@ -1424,6 +1424,42 @@ void wallet2::check_genesis(const crypto::hash& genesis_hash) const {
|
||||||
//----------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------
|
||||||
void wallet2::store()
|
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;
|
std::stringstream oss;
|
||||||
boost::archive::binary_oarchive ar(oss);
|
boost::archive::binary_oarchive ar(oss);
|
||||||
ar << *this;
|
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]);
|
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;
|
cache_file_data.cache_data = cipher;
|
||||||
|
|
||||||
// save to new file, rename main to old, rename new to main
|
const std::string new_file = same_file ? m_wallet_file + ".new" : path;
|
||||||
// at all times, there should be a valid file on disk
|
const std::string old_file = m_wallet_file;
|
||||||
const std::string new_file = m_wallet_file + ".new";
|
const std::string old_keys_file = m_keys_file;
|
||||||
const std::string old_file = m_wallet_file + ".old";
|
const std::string old_address_file = m_wallet_file + ".address.txt";
|
||||||
|
|
||||||
// save to new file
|
// save to new file
|
||||||
std::ofstream ostr;
|
std::ofstream ostr;
|
||||||
|
@ -1451,87 +1487,35 @@ void wallet2::store()
|
||||||
ostr.close();
|
ostr.close();
|
||||||
THROW_WALLET_EXCEPTION_IF(!success || !ostr.good(), error::file_save_error, new_file);
|
THROW_WALLET_EXCEPTION_IF(!success || !ostr.good(), error::file_save_error, new_file);
|
||||||
|
|
||||||
// rename
|
// save keys to the new file
|
||||||
boost::filesystem::remove(old_file); // probably does not exist
|
// if we here, main wallet file is saved and we only need to save keys and address files
|
||||||
if (boost::filesystem::exists(m_wallet_file)) {
|
if (!same_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
|
|
||||||
prepare_file_names(path);
|
prepare_file_names(path);
|
||||||
store_keys(m_keys_file, password, false);
|
store_keys(m_keys_file, password, false);
|
||||||
|
|
||||||
// save address to the new file
|
// save address to the new file
|
||||||
const std::string address_file = m_wallet_file + ".address.txt";
|
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));
|
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);
|
THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file);
|
||||||
|
|
||||||
|
|
||||||
// remove old wallet file
|
// remove old wallet file
|
||||||
r = boost::filesystem::remove(old_file);
|
r = boost::filesystem::remove(old_file);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
LOG_ERROR("error removing file: " << old_file);
|
LOG_ERROR("error removing file: " << old_file);
|
||||||
}
|
}
|
||||||
// remove old keys file
|
// remove old keys file
|
||||||
r = boost::filesystem::remove(old_keys_file);
|
r = boost::filesystem::remove(old_keys_file);
|
||||||
if (!r) {
|
if (!r) {
|
||||||
LOG_ERROR("error removing file: " << old_keys_file);
|
LOG_ERROR("error removing file: " << old_keys_file);
|
||||||
}
|
}
|
||||||
// remove old address file
|
// remove old address file
|
||||||
r = boost::filesystem::remove(old_address_file);
|
r = boost::filesystem::remove(old_address_file);
|
||||||
if (!r) {
|
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
|
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
|
std::string wallet2::get_wallet_file() const
|
||||||
{
|
{
|
||||||
return m_wallet_file;
|
return m_wallet_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string wallet2::get_keys_file() const
|
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);
|
virtual bool closeWallet(Wallet *wallet);
|
||||||
bool walletExists(const std::string &path);
|
bool walletExists(const std::string &path);
|
||||||
std::string errorString() const;
|
std::string errorString() const;
|
||||||
|
void setDaemonHost(const std::string &hostname);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -329,6 +330,11 @@ std::string WalletManagerImpl::errorString() const
|
||||||
return m_errorString;
|
return m_errorString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WalletManagerImpl::setDaemonHost(const std::string &hostname)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
///////////////////// WalletManagerFactory implementation //////////////////////
|
///////////////////// WalletManagerFactory implementation //////////////////////
|
||||||
|
|
|
@ -112,6 +112,9 @@ struct WalletManager
|
||||||
|
|
||||||
virtual std::string errorString() const = 0;
|
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));
|
ASSERT_TRUE(wmgr->closeWallet(wallet2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_F(WalletManagerTest, WalletManagerStoresWallet2)
|
TEST_F(WalletManagerTest, WalletManagerStoresWallet2)
|
||||||
{
|
{
|
||||||
Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG);
|
Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG);
|
||||||
|
@ -181,6 +182,7 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet2)
|
||||||
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
ASSERT_TRUE(wmgr->closeWallet(wallet1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_F(WalletManagerTest, WalletManagerStoresWallet3)
|
TEST_F(WalletManagerTest, WalletManagerStoresWallet3)
|
||||||
{
|
{
|
||||||
Bitmonero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG);
|
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)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
//epee::debug::get_set_enable_assert(true, false);
|
//epee::debug::get_set_enable_assert(true, false);
|
||||||
|
|
Loading…
Reference in New Issue