Merge branch 'develop' into ui_develop
This commit is contained in:
commit
60d6c44fb9
28 changed files with 607 additions and 91 deletions
|
|
@ -189,6 +189,13 @@ if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
|||
set(Boost_LIBRARY_DIRS "/Users/roky/projects/Zano/mobile_repo/ofxiOSBoost/libs/boost/ios/")
|
||||
set(Boost_LIBRARIES "libboost.a")
|
||||
set(Boost_VERSION "ofxiOSBoost 1.60.0")
|
||||
#workaround for new XCode 12 policy for builds(now it includes a slice for the "arm64" when builds for simulator)
|
||||
set(__iphoneos_archs "armv7 armv7s arm64")
|
||||
set(__iphonesimulator_archs "i386 x86_64")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphoneos*] "${__iphoneos_archs}")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphoneos*] "${__iphoneos_archs}")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}")
|
||||
set(CMAKE_XCODE_ATTRIBUTE_VALID_ARCHS[sdk=iphonesimulator*] "${__iphonesimulator_archs}")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
set(Boost_INCLUDE_DIRS "/Users/roky/projects/Zano/mobile_repo/Boost-for-Android-Prebuilt/1.69.0/include")
|
||||
set(Boost_LIBRARY_DIRS "/Users/roky/projects/Zano/mobile_repo/Boost-for-Android-Prebuilt/1.69.0/libs/llvm/${CMAKE_ANDROID_ARCH_ABI}/")
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ namespace tools
|
|||
std::list<currency::block> blocks;
|
||||
std::list<currency::transaction> txs;
|
||||
bool r = source_core.get_blocks(i, 1, blocks, txs);
|
||||
CHECK_AND_ASSERT_MES(r && blocks.size()==1, false, "Filed to get block " << i << " from core");
|
||||
CHECK_AND_ASSERT_MES(r && blocks.size()==1, false, "Failed to get block " << i << " from core");
|
||||
currency::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||
crypto::hash tx_hash = AUTO_VAL_INIT(tx_hash);
|
||||
for (auto& tx : txs)
|
||||
|
|
|
|||
|
|
@ -60,18 +60,42 @@ namespace currency
|
|||
return m_keys;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
std::string account_base::get_seed_phrase() const
|
||||
void crypt_with_pass(const void* scr_data, std::size_t src_length, void* dst_data, const std::string& password)
|
||||
{
|
||||
crypto::chacha8_key key = AUTO_VAL_INIT(key);
|
||||
crypto::generate_chacha8_key(password, key);
|
||||
crypto::hash pass_hash = crypto::cn_fast_hash(password.data(), password.size());
|
||||
crypto::chacha8_iv iv = AUTO_VAL_INIT(iv);
|
||||
CHECK_AND_ASSERT_THROW_MES(sizeof(pass_hash) >= sizeof(iv), "Invalid configuration: hash size is less than keys_file_data.iv");
|
||||
iv = *((crypto::chacha8_iv*)&pass_hash);
|
||||
crypto::chacha8(scr_data, src_length, key, iv, (char*)dst_data);
|
||||
}
|
||||
|
||||
|
||||
std::string account_base::get_seed_phrase(const std::string& password) const
|
||||
{
|
||||
if (m_keys_seed_binary.empty())
|
||||
return "";
|
||||
std::string keys_seed_text = tools::mnemonic_encoding::binary2text(m_keys_seed_binary);
|
||||
std::string timestamp_word = currency::get_word_from_timstamp(m_creation_timestamp);
|
||||
|
||||
std::vector<unsigned char> processed_seed_binary = m_keys_seed_binary;
|
||||
if (!password.empty())
|
||||
{
|
||||
//encrypt seed phrase binary data
|
||||
crypt_with_pass(&m_keys_seed_binary[0], m_keys_seed_binary.size(), &processed_seed_binary[0], password);
|
||||
}
|
||||
|
||||
std::string keys_seed_text = tools::mnemonic_encoding::binary2text(processed_seed_binary);
|
||||
std::string timestamp_word = currency::get_word_from_timstamp(m_creation_timestamp, !password.empty());
|
||||
|
||||
// floor creation time to WALLET_BRAIN_DATE_QUANTUM to make checksum calculation stable
|
||||
uint64_t creation_timestamp_rounded = get_timstamp_from_word(timestamp_word);
|
||||
bool self_check_is_password_used = false;
|
||||
uint64_t creation_timestamp_rounded = get_timstamp_from_word(timestamp_word, self_check_is_password_used);
|
||||
CHECK_AND_ASSERT_THROW_MES(self_check_is_password_used == !password.empty(), "Account seed phrase internal error: password flag encoded wrong");
|
||||
|
||||
constexpr uint16_t checksum_max = tools::mnemonic_encoding::NUMWORDS >> 1; // maximum value of checksum
|
||||
crypto::hash h = crypto::cn_fast_hash(m_keys_seed_binary.data(), m_keys_seed_binary.size());
|
||||
std::string binary_for_check_sum((const char*)&m_keys_seed_binary[0], m_keys_seed_binary.size());
|
||||
binary_for_check_sum.append(password);
|
||||
crypto::hash h = crypto::cn_fast_hash(binary_for_check_sum.data(), binary_for_check_sum.size());
|
||||
*reinterpret_cast<uint64_t*>(&h) = creation_timestamp_rounded;
|
||||
h = crypto::cn_fast_hash(&h, sizeof h);
|
||||
uint64_t h_64 = *reinterpret_cast<uint64_t*>(&h);
|
||||
|
|
@ -104,7 +128,7 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::restore_from_seed_phrase(const std::string& seed_phrase)
|
||||
bool account_base::restore_from_seed_phrase(const std::string& seed_phrase, const std::string& seed_password)
|
||||
{
|
||||
//cut the last timestamp word from restore_dats
|
||||
std::list<std::string> words;
|
||||
|
|
@ -138,9 +162,20 @@ namespace currency
|
|||
auditable_flag_and_checksum = tools::mnemonic_encoding::num_by_word(auditable_flag_and_checksum_word);
|
||||
|
||||
std::vector<unsigned char> keys_seed_binary = tools::mnemonic_encoding::text2binary(keys_seed_text);
|
||||
CHECK_AND_ASSERT_MES(keys_seed_binary.size(), false, "text2binary failed to convert the given text"); // don't prints event incorrect seed into the log for security
|
||||
std::vector<unsigned char> keys_seed_processed_binary = keys_seed_binary;
|
||||
|
||||
m_creation_timestamp = get_timstamp_from_word(timestamp_word);
|
||||
|
||||
bool has_password = false;
|
||||
m_creation_timestamp = get_timstamp_from_word(timestamp_word, has_password);
|
||||
//double check is password setting from timestamp word match with passed parameters
|
||||
CHECK_AND_ASSERT_MES(has_password != seed_password.empty(), false, "Seed phrase password wrong interpretation");
|
||||
if (has_password)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(!seed_password.empty(), false, "Seed phrase password wrong interpretation: internal error");
|
||||
crypt_with_pass(&keys_seed_binary[0], keys_seed_binary.size(), &keys_seed_processed_binary[0], seed_password);
|
||||
}
|
||||
|
||||
CHECK_AND_ASSERT_MES(keys_seed_processed_binary.size(), false, "text2binary failed to convert the given text"); // don't prints event incorrect seed into the log for security
|
||||
|
||||
bool auditable_flag = false;
|
||||
|
||||
|
|
@ -150,7 +185,9 @@ namespace currency
|
|||
auditable_flag = (auditable_flag_and_checksum & 1) != 0; // auditable flag is the lower 1 bit
|
||||
uint16_t checksum = static_cast<uint16_t>(auditable_flag_and_checksum >> 1); // checksum -- everything else
|
||||
constexpr uint16_t checksum_max = tools::mnemonic_encoding::NUMWORDS >> 1; // maximum value of checksum
|
||||
crypto::hash h = crypto::cn_fast_hash(keys_seed_binary.data(), keys_seed_binary.size());
|
||||
std::string binary_for_check_sum((const char*)&keys_seed_processed_binary[0], keys_seed_processed_binary.size());
|
||||
binary_for_check_sum.append(seed_password);
|
||||
crypto::hash h = crypto::cn_fast_hash(binary_for_check_sum.data(), binary_for_check_sum.size());
|
||||
*reinterpret_cast<uint64_t*>(&h) = m_creation_timestamp;
|
||||
h = crypto::cn_fast_hash(&h, sizeof h);
|
||||
uint64_t h_64 = *reinterpret_cast<uint64_t*>(&h);
|
||||
|
|
@ -158,10 +195,10 @@ namespace currency
|
|||
CHECK_AND_ASSERT_MES(checksum == checksum_calculated, false, "seed phase has invalid checksum: " << checksum_calculated << ", while " << checksum << " is expected, check your words");
|
||||
}
|
||||
|
||||
bool r = restore_keys(keys_seed_binary);
|
||||
bool r = restore_keys(keys_seed_processed_binary);
|
||||
CHECK_AND_ASSERT_MES(r, false, "restore_keys failed");
|
||||
|
||||
m_keys_seed_binary = keys_seed_binary;
|
||||
m_keys_seed_binary = keys_seed_processed_binary;
|
||||
|
||||
if (auditable_flag)
|
||||
m_keys.account_address.flags |= ACCOUNT_PUBLIC_ADDRESS_FLAG_AUDITABLE;
|
||||
|
|
@ -169,6 +206,34 @@ namespace currency
|
|||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::is_seed_password_protected(const std::string& seed_phrase, bool& is_password_protected)
|
||||
{
|
||||
//cut the last timestamp word from restore_dats
|
||||
std::list<std::string> words;
|
||||
boost::split(words, seed_phrase, boost::is_space());
|
||||
|
||||
std::string timestamp_word;
|
||||
if (words.size() == SEED_PHRASE_V1_WORDS_COUNT)
|
||||
{
|
||||
// 24 seed words + one timestamp word = 25 total
|
||||
timestamp_word = words.back();
|
||||
}
|
||||
else if (words.size() == SEED_PHRASE_V2_WORDS_COUNT)
|
||||
{
|
||||
// 24 seed words + one timestamp word + one flags & checksum = 26 total
|
||||
words.erase(--words.end());
|
||||
timestamp_word = words.back();
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
get_timstamp_from_word(timestamp_word, is_password_protected);
|
||||
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------
|
||||
bool account_base::restore_from_tracking_seed(const std::string& tracking_seed)
|
||||
{
|
||||
set_null();
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ namespace currency
|
|||
const account_public_address& get_public_address() const { return m_keys.account_address; };
|
||||
std::string get_public_address_str() const;
|
||||
|
||||
std::string get_seed_phrase() const;
|
||||
std::string get_seed_phrase(const std::string& seed_password) const;
|
||||
std::string get_tracking_seed() const;
|
||||
bool restore_from_seed_phrase(const std::string& seed_phrase);
|
||||
bool restore_from_seed_phrase(const std::string& seed_phrase, const std::string& seed_password);
|
||||
bool restore_from_tracking_seed(const std::string& tracking_seed);
|
||||
|
||||
uint64_t get_createtime() const { return m_creation_timestamp; }
|
||||
|
|
@ -65,6 +65,8 @@ namespace currency
|
|||
bool store(const std::string& file_path);
|
||||
|
||||
void make_account_watch_only();
|
||||
bool is_watch_only() const { return m_keys.spend_secret_key == currency::null_skey; }
|
||||
bool is_auditable() const { return m_keys.account_address.is_auditable(); }
|
||||
|
||||
template <class t_archive>
|
||||
inline void serialize(t_archive &a, const unsigned int /*ver*/)
|
||||
|
|
@ -76,6 +78,7 @@ namespace currency
|
|||
|
||||
static std::string vector_of_chars_to_string(const std::vector<unsigned char>& v) { return std::string(v.begin(), v.end()); }
|
||||
static std::vector<unsigned char> string_to_vector_of_chars(const std::string& v) { return std::vector<unsigned char>(v.begin(), v.end()); }
|
||||
static bool is_seed_password_protected(const std::string& seed_phrase, bool& is_password_protected);
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(m_keys)
|
||||
|
|
|
|||
|
|
@ -150,9 +150,10 @@
|
|||
|
||||
#define WALLET_FILE_MAX_KEYS_SIZE 10000 //
|
||||
#define WALLET_BRAIN_DATE_OFFSET 1543622400
|
||||
#define WALLET_BRAIN_DATE_QUANTUM 604800 //by last word we encode a number of week since launch of the project,
|
||||
#define WALLET_BRAIN_DATE_QUANTUM 604800 //by last word we encode a number of week since launch of the project AND password flag,
|
||||
//which let us to address tools::mnemonic_encoding::NUMWORDS weeks after project launch
|
||||
//which is about 30 years
|
||||
//which is about 15 years
|
||||
#define WALLET_BRAIN_DATE_MAX_WEEKS_COUNT 800
|
||||
|
||||
#define OFFER_MAXIMUM_LIFE_TIME (60*60*24*30) // 30 days
|
||||
|
||||
|
|
|
|||
|
|
@ -1316,21 +1316,34 @@ namespace currency
|
|||
return reward;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
std::string get_word_from_timstamp(uint64_t timestamp)
|
||||
std::string get_word_from_timstamp(uint64_t timestamp, bool use_password)
|
||||
{
|
||||
uint64_t date_offset = timestamp > WALLET_BRAIN_DATE_OFFSET ? timestamp - WALLET_BRAIN_DATE_OFFSET : 0;
|
||||
uint64_t weeks_count = date_offset / WALLET_BRAIN_DATE_QUANTUM;
|
||||
CHECK_AND_ASSERT_THROW_MES(weeks_count < WALLET_BRAIN_DATE_MAX_WEEKS_COUNT, "SEED PHRASE need to be extended or refactored");
|
||||
|
||||
if (use_password)
|
||||
weeks_count += WALLET_BRAIN_DATE_MAX_WEEKS_COUNT;
|
||||
|
||||
CHECK_AND_ASSERT_THROW_MES(weeks_count < std::numeric_limits<uint32_t>::max(), "internal error: unable to convert to uint32, val = " << weeks_count);
|
||||
uint32_t weeks_count_32 = static_cast<uint32_t>(weeks_count);
|
||||
|
||||
return tools::mnemonic_encoding::word_by_num(weeks_count_32);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
uint64_t get_timstamp_from_word(std::string word)
|
||||
uint64_t get_timstamp_from_word(std::string word, bool& password_used)
|
||||
{
|
||||
uint64_t count_of_weeks = tools::mnemonic_encoding::num_by_word(word);
|
||||
if (count_of_weeks >= WALLET_BRAIN_DATE_MAX_WEEKS_COUNT)
|
||||
{
|
||||
count_of_weeks -= WALLET_BRAIN_DATE_MAX_WEEKS_COUNT;
|
||||
password_used = true;
|
||||
}
|
||||
else {
|
||||
password_used = false;
|
||||
}
|
||||
uint64_t timestamp = count_of_weeks * WALLET_BRAIN_DATE_QUANTUM + WALLET_BRAIN_DATE_OFFSET;
|
||||
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -291,8 +291,8 @@ namespace currency
|
|||
bool fill_tx_rpc_details(tx_rpc_extended_info& tei, const transaction& tx, const transaction_chain_entry* ptce, const crypto::hash& h, uint64_t timestamp, bool is_short = false);
|
||||
bool fill_block_rpc_details(block_rpc_extended_info& pei_rpc, const block_extended_info& bei_chain, const crypto::hash& h);
|
||||
void append_per_block_increments_for_tx(const transaction& tx, std::unordered_map<uint64_t, uint32_t>& gindices);
|
||||
std::string get_word_from_timstamp(uint64_t timestamp);
|
||||
uint64_t get_timstamp_from_word(std::string word);
|
||||
std::string get_word_from_timstamp(uint64_t timestamp, bool use_password);
|
||||
uint64_t get_timstamp_from_word(std::string word, bool& password_used);
|
||||
|
||||
template<class t_txin_v>
|
||||
typename std::conditional<std::is_const<t_txin_v>::value, const std::vector<txin_etc_details_v>, std::vector<txin_etc_details_v> >::type& get_txin_etc_options(t_txin_v& in)
|
||||
|
|
|
|||
|
|
@ -239,6 +239,28 @@ QString MainWindow::get_tx_pool_info()
|
|||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
QString MainWindow::request_dummy()
|
||||
{
|
||||
static int code_ = 0;
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
PREPARE_RESPONSE(currency::COMMAND_RPC_GET_POOL_INFO::response, ar);
|
||||
if (code_ == 2)
|
||||
{
|
||||
code_ = -1;
|
||||
ar.error_code = API_RETURN_CODE_CORE_BUSY;
|
||||
}
|
||||
else
|
||||
{
|
||||
ar.error_code = API_RETURN_CODE_OK;
|
||||
}
|
||||
|
||||
++code_;
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
|
||||
QString MainWindow::get_default_fee()
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
@ -1654,7 +1676,7 @@ QString MainWindow::restore_wallet(const QString& param)
|
|||
//return que_call2<view::restore_wallet_request>("restore_wallet", param, [this](const view::restore_wallet_request& owd, view::api_response& ar){
|
||||
PREPARE_ARG_FROM_JSON(view::restore_wallet_request, owd);
|
||||
PREPARE_RESPONSE(view::open_wallet_response, ar);
|
||||
ar.error_code = m_backend.restore_wallet(epee::string_encoding::utf8_to_wstring(owd.path), owd.pass, owd.restore_key, ar.response_data);
|
||||
ar.error_code = m_backend.restore_wallet(epee::string_encoding::utf8_to_wstring(owd.path), owd.pass, owd.seed_phrase, owd.seed_pass, ar.response_data);
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
|
@ -1855,9 +1877,9 @@ QString MainWindow::get_smart_wallet_info(const QString& param)
|
|||
{
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
PREPARE_ARG_FROM_JSON(view::wallet_id_obj, wo);
|
||||
PREPARE_ARG_FROM_JSON(view::request_get_smart_wallet_info, wo);
|
||||
PREPARE_RESPONSE(view::get_restore_info_response, ar);
|
||||
ar.error_code = m_backend.get_wallet_restore_info(wo.wallet_id, ar.response_data.restore_key);
|
||||
ar.error_code = m_backend.get_wallet_restore_info(wo.wallet_id, ar.response_data.seed_phrase, wo.seed_password);
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
|
@ -1951,14 +1973,26 @@ QString MainWindow::open_url_in_browser(const QString& param)
|
|||
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
|
||||
QString MainWindow::is_valid_restore_wallet_text(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
return m_backend.is_valid_brain_restore_data(param.toStdString()).c_str();
|
||||
PREPARE_ARG_FROM_JSON(view::seed_info_param, rwtp);
|
||||
return m_backend.is_valid_brain_restore_data(rwtp.seed_phrase, rwtp.seed_password).c_str();
|
||||
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
|
||||
}
|
||||
|
||||
QString MainWindow::get_seed_phrase_info(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
PREPARE_ARG_FROM_JSON(view::seed_info_param, rwtp);
|
||||
PREPARE_RESPONSE(view::seed_phrase_info, ar);
|
||||
ar.error_code = m_backend.get_seed_phrase_info(rwtp.seed_phrase, rwtp.seed_password, ar.response_data).c_str();
|
||||
return MAKE_RESPONSE(ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
void MainWindow::contextMenuEvent(QContextMenuEvent * event)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ public:
|
|||
QString is_autostart_enabled();
|
||||
QString toggle_autostart(const QString& param);
|
||||
QString is_valid_restore_wallet_text(const QString& param);
|
||||
QString get_seed_phrase_info(const QString& param);
|
||||
QString print_text(const QString& param);
|
||||
QString print_log(const QString& param);
|
||||
QString set_clipboard(const QString& param);
|
||||
|
|
@ -159,6 +160,9 @@ public:
|
|||
QString is_remnotenode_mode_preconfigured();
|
||||
QString start_backend(const QString& params);
|
||||
|
||||
//for test purposes onlys
|
||||
QString request_dummy();
|
||||
|
||||
signals:
|
||||
void quit_requested(const QString str);
|
||||
void update_daemon_state(const QString str);
|
||||
|
|
|
|||
|
|
@ -46,13 +46,14 @@ namespace
|
|||
const command_line::arg_descriptor<std::string> arg_password = {"password", "Wallet password", "", true};
|
||||
const command_line::arg_descriptor<bool> arg_dont_refresh = { "no-refresh", "Do not refresh after load", false, true };
|
||||
const command_line::arg_descriptor<bool> arg_dont_set_date = { "no-set-creation-date", "Do not set wallet creation date", false, false };
|
||||
const command_line::arg_descriptor<bool> arg_print_brain_wallet = { "print-brain-wallet", "Print to conosole brain wallet", false, false };
|
||||
const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", "Use daemon instance at port <arg> instead of default", 0};
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level = {"set-log", "", 0, true};
|
||||
const command_line::arg_descriptor<bool> arg_do_pos_mining = { "do-pos-mining", "Do PoS mining", false, false };
|
||||
const command_line::arg_descriptor<std::string> arg_pos_mining_reward_address = { "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" };
|
||||
const command_line::arg_descriptor<std::string> arg_restore_wallet = { "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to <arg>", "" };
|
||||
const command_line::arg_descriptor<bool> arg_offline_mode = { "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)", false, true };
|
||||
const command_line::arg_descriptor<std::string> arg_scan_for_wallet = { "scan-for-wallet", "", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_addr_to_compare = { "addr-to-compare", "", "", true };
|
||||
|
||||
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
|
||||
|
||||
|
|
@ -178,7 +179,6 @@ bool simple_wallet::help(const std::vector<std::string> &args/* = std::vector<st
|
|||
|
||||
simple_wallet::simple_wallet()
|
||||
: m_daemon_port(0),
|
||||
m_print_brain_wallet(false),
|
||||
m_do_refresh_after_load(false),
|
||||
m_do_not_set_date(false),
|
||||
m_do_pos_mining(false),
|
||||
|
|
@ -307,10 +307,6 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
|||
m_do_refresh_after_load = false;
|
||||
}
|
||||
|
||||
if (command_line::has_arg(vm, arg_print_brain_wallet))
|
||||
{
|
||||
m_print_brain_wallet = true;
|
||||
}
|
||||
|
||||
if (!m_generate_new.empty())
|
||||
{
|
||||
|
|
@ -336,9 +332,26 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
|||
fail_msg_writer() << "failed to read seed phrase";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool looks_like_tracking_seed = restore_seed_container.password().find(':') != std::string::npos;
|
||||
bool r = restore_wallet(m_restore_wallet, restore_seed_container.password(), pwd_container.password(), looks_like_tracking_seed);
|
||||
tools::password_container seed_password_container;
|
||||
|
||||
if (!looks_like_tracking_seed)
|
||||
{
|
||||
bool is_password_protected = false;
|
||||
bool sr = account_base::is_seed_password_protected(restore_seed_container.password(), is_password_protected);
|
||||
if (!sr)
|
||||
{
|
||||
fail_msg_writer() << "failed to parse seed phrase";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_password_protected && !seed_password_container.read_password("This seed is secured, to use it please enter the password:\n"))
|
||||
{
|
||||
fail_msg_writer() << "failed to read seed phrase";
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool r = restore_wallet(m_restore_wallet, restore_seed_container.password(), pwd_container.password(), looks_like_tracking_seed, seed_password_container.password());
|
||||
CHECK_AND_ASSERT_MES(r, false, "wallet restoring failed");
|
||||
}
|
||||
else
|
||||
|
|
@ -400,10 +413,6 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
|||
if (m_do_not_set_date)
|
||||
m_wallet->reset_creation_time(0);
|
||||
|
||||
if (m_print_brain_wallet)
|
||||
{
|
||||
std::cout << "Seed phrase (keep it in secret): " << m_wallet->get_account().get_seed_phrase() << std::endl << std::flush;
|
||||
}
|
||||
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
|
@ -422,7 +431,7 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas
|
|||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::string& seed_or_tracking_seed, const std::string& password, bool tracking_wallet)
|
||||
bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::string& seed_or_tracking_seed, const std::string& password, bool tracking_wallet, const std::string& seed_password)
|
||||
{
|
||||
m_wallet_file = wallet_file;
|
||||
|
||||
|
|
@ -434,13 +443,13 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
if (tracking_wallet)
|
||||
{
|
||||
// auditable watch-only aka tracking wallet
|
||||
m_wallet->restore(epee::string_encoding::utf8_to_wstring(wallet_file), password, seed_or_tracking_seed, true);
|
||||
m_wallet->restore(epee::string_encoding::utf8_to_wstring(wallet_file), password, seed_or_tracking_seed, true, "");
|
||||
message_writer(epee::log_space::console_color_white, true) << "Tracking wallet restored: " << m_wallet->get_account().get_public_address_str();
|
||||
}
|
||||
else
|
||||
{
|
||||
// normal or auditable wallet
|
||||
m_wallet->restore(epee::string_encoding::utf8_to_wstring(wallet_file), password, seed_or_tracking_seed, false);
|
||||
m_wallet->restore(epee::string_encoding::utf8_to_wstring(wallet_file), password, seed_or_tracking_seed, false, seed_password);
|
||||
message_writer(epee::log_space::console_color_white, true) << (m_wallet->is_auditable() ? "Auditable wallet" : "Wallet") << " restored: " << m_wallet->get_account().get_public_address_str();
|
||||
std::cout << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().view_secret_key) << std::endl << std::flush;
|
||||
if (m_wallet->is_auditable())
|
||||
|
|
@ -454,7 +463,11 @@ bool simple_wallet::restore_wallet(const std::string& wallet_file, const std::st
|
|||
fail_msg_writer() << "failed to restore wallet, check your " << (tracking_wallet ? "tracking seed!" : "seed phrase!") << ENDL << e.what();
|
||||
return false;
|
||||
}
|
||||
|
||||
catch (...)
|
||||
{
|
||||
fail_msg_writer() << "failed to restore wallet, check your " << (tracking_wallet ? "tracking seed!" : "seed phrase!") << ENDL;
|
||||
return false;
|
||||
}
|
||||
m_wallet->init(m_daemon_address);
|
||||
|
||||
success_msg_writer() <<
|
||||
|
|
@ -482,9 +495,6 @@ bool simple_wallet::open_wallet(const string &wallet_file, const std::string& pa
|
|||
m_wallet->load(epee::string_encoding::utf8_to_wstring(m_wallet_file), password);
|
||||
message_writer(epee::log_space::console_color_white, true) << "Opened" << (m_wallet->is_auditable() ? " auditable" : "") << (m_wallet->is_watch_only() ? " watch-only" : "") << " wallet: " << m_wallet->get_account().get_public_address_str();
|
||||
|
||||
if (m_print_brain_wallet)
|
||||
std::cout << "Seed phrase (keep it in secret): " << m_wallet->get_account().get_seed_phrase() << std::endl << std::flush;
|
||||
|
||||
break;
|
||||
}
|
||||
catch (const tools::error::wallet_load_notice_wallet_restored& /*e*/)
|
||||
|
|
@ -1359,9 +1369,24 @@ bool simple_wallet::print_address(const std::vector<std::string> &args/* = std::
|
|||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::show_seed(const std::vector<std::string> &args)
|
||||
{
|
||||
success_msg_writer() << "Here's your wallet's seed phrase. Write it down and keep in a safe place.";
|
||||
success_msg_writer(true) << "Anyone who knows the following 26 words can access your wallet:";
|
||||
std::cout << m_wallet->get_account().get_seed_phrase() << std::endl << std::flush;
|
||||
success_msg_writer() << "Please enter a password to secure this seed. Securing your seed is HIGHLY recommended. Leave password blank to stay unsecured.";
|
||||
success_msg_writer(true) << "Remember, restoring a wallet from Secured Seed can only be done if you know its password.";
|
||||
|
||||
tools::password_container seed_password_container1;
|
||||
if (!seed_password_container1.read_password("Enter seed password: "))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
tools::password_container seed_password_container2;
|
||||
if (!seed_password_container2.read_password("Confirm seed password: "))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if(seed_password_container1.password() != seed_password_container2.password())
|
||||
{
|
||||
std::cout << "Error: password mismatch. Please make sure you entered the correct password and confirmed it" << std::endl << std::flush;
|
||||
}
|
||||
std::cout << m_wallet->get_account().get_seed_phrase(seed_password_container2.password()) << std::endl << std::flush;
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
|
|
@ -1712,6 +1737,109 @@ bool simple_wallet::sweep_below(const std::vector<std::string> &args)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t
|
||||
get_tick_count__()
|
||||
{
|
||||
using namespace std::chrono;
|
||||
return duration_cast<milliseconds>(steady_clock::now().time_since_epoch()).count();
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool check_if_file_looks_like_a_wallet(const std::wstring& wallet_)
|
||||
{
|
||||
std::string keys_buff;
|
||||
|
||||
|
||||
boost::system::error_code e;
|
||||
bool exists = boost::filesystem::exists(wallet_, e);
|
||||
if (e || !exists)
|
||||
return false;
|
||||
|
||||
boost::filesystem::ifstream data_file;
|
||||
data_file.open(wallet_, std::ios_base::binary | std::ios_base::in);
|
||||
if (data_file.fail())
|
||||
return false;
|
||||
|
||||
tools::wallet_file_binary_header wbh = AUTO_VAL_INIT(wbh);
|
||||
|
||||
data_file.read((char*)&wbh, sizeof(wbh));
|
||||
if (data_file.fail())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (wbh.m_signature != WALLET_FILE_SIGNATURE_OLD && wbh.m_signature != WALLET_FILE_SIGNATURE_V2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//std::cout << "\r \r";
|
||||
LOG_PRINT_L0("Found wallet file: " << epee::string_encoding::convert_to_ansii(wallet_));
|
||||
return false;
|
||||
}
|
||||
|
||||
bool search_for_wallet_file(const std::wstring &search_here/*, const std::string &addr_to_compare*/)
|
||||
{
|
||||
if (search_here == L"/proc" || search_here == L"/bin" || search_here == L"/dev" || search_here == L"/etc"
|
||||
|| search_here == L"/lib" || search_here == L"/lib64" || search_here == L"/proc" || search_here == L"/run"
|
||||
|| search_here == L"/sbin" || search_here == L"/srv" || search_here == L"/sys" || search_here == L"/usr"
|
||||
|| search_here == L"/var")
|
||||
{
|
||||
LOG_PRINT_L0("Skiping " << epee::string_encoding::convert_to_ansii(search_here));
|
||||
return false;
|
||||
}
|
||||
|
||||
//LOG_PRINT_L0("FOLDER: " << epee::string_encoding::convert_to_ansii(search_here));
|
||||
static uint64_t last_tick = 0;
|
||||
using namespace boost::filesystem;
|
||||
//recursive_directory_iterator dir(search_here), end;
|
||||
try
|
||||
{
|
||||
for (auto& dir : boost::make_iterator_range(directory_iterator(search_here), {}))
|
||||
{
|
||||
boost::system::error_code ec = AUTO_VAL_INIT(ec);
|
||||
bool r = boost::filesystem::is_directory(dir.path(), ec);
|
||||
if (r)
|
||||
{
|
||||
if (get_tick_count__() - last_tick > 300)
|
||||
{
|
||||
last_tick = get_tick_count__();
|
||||
//std::cout << "\r \r ->" << dir.path();
|
||||
}
|
||||
bool r = search_for_wallet_file(dir.path().wstring());
|
||||
if (r)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
boost::system::error_code ec = AUTO_VAL_INIT(ec);
|
||||
bool r = boost::filesystem::is_regular_file(dir.path(), ec);
|
||||
if (!r)
|
||||
{
|
||||
//LOG_PRINT_L0("Skiping as not regular: " << epee::string_encoding::convert_to_ansii(dir.path().wstring()));
|
||||
return false;
|
||||
|
||||
}
|
||||
//LOG_PRINT_L0("FILE: " << dir.path().string());
|
||||
std::wstring pa = dir.path().wstring();
|
||||
r = check_if_file_looks_like_a_wallet(pa);
|
||||
if (r)
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (std::exception& /* ex*/)
|
||||
{
|
||||
//std::cout << "\r \r";
|
||||
LOG_PRINT_CYAN("Skip: " << search_here, LOG_LEVEL_0);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32
|
||||
int wmain( int argc, wchar_t* argv_w[ ], wchar_t* envp[ ] )
|
||||
|
|
@ -1763,14 +1891,14 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_params, arg_log_level);
|
||||
command_line::add_arg(desc_params, arg_dont_refresh);
|
||||
command_line::add_arg(desc_params, arg_dont_set_date);
|
||||
command_line::add_arg(desc_params, arg_print_brain_wallet);
|
||||
command_line::add_arg(desc_params, arg_do_pos_mining);
|
||||
command_line::add_arg(desc_params, arg_pos_mining_reward_address);
|
||||
command_line::add_arg(desc_params, arg_restore_wallet);
|
||||
command_line::add_arg(desc_params, arg_offline_mode);
|
||||
command_line::add_arg(desc_params, command_line::arg_log_file);
|
||||
command_line::add_arg(desc_params, command_line::arg_log_level);
|
||||
|
||||
command_line::add_arg(desc_params, arg_scan_for_wallet);
|
||||
command_line::add_arg(desc_params, arg_addr_to_compare);
|
||||
|
||||
tools::wallet_rpc_server::init_options(desc_params);
|
||||
|
||||
|
|
@ -1827,6 +1955,17 @@ int main(int argc, char* argv[])
|
|||
log_space::get_set_log_detalisation_level(true, command_line::get_arg(vm, command_line::arg_log_level));
|
||||
}
|
||||
|
||||
|
||||
if (command_line::has_arg(vm, arg_scan_for_wallet))
|
||||
{
|
||||
log_space::log_singletone::add_logger(LOGGER_CONSOLE, nullptr, nullptr, LOG_LEVEL_4);
|
||||
LOG_PRINT_L0("Searching from "
|
||||
<< epee::string_encoding::convert_to_ansii(command_line::get_arg(vm, arg_scan_for_wallet)));
|
||||
|
||||
search_for_wallet_file(epee::string_encoding::convert_to_unicode(command_line::get_arg(vm, arg_scan_for_wallet)));
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
bool offline_mode = command_line::get_arg(vm, arg_offline_mode);
|
||||
|
||||
if (command_line::has_arg(vm, tools::wallet_rpc_server::arg_rpc_bind_port))
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ namespace currency
|
|||
|
||||
bool new_wallet(const std::string &wallet_file, const std::string& password, bool create_auditable_wallet);
|
||||
bool open_wallet(const std::string &wallet_file, const std::string& password);
|
||||
bool restore_wallet(const std::string& wallet_file, const std::string& seed_or_tracking_seed, const std::string& password, bool tracking_wallet);
|
||||
bool restore_wallet(const std::string& wallet_file, const std::string& seed_or_tracking_seed, const std::string& password, bool tracking_wallet, const std::string& seed_password);
|
||||
bool close_wallet();
|
||||
|
||||
bool help(const std::vector<std::string> &args = std::vector<std::string>());
|
||||
|
|
@ -163,7 +163,6 @@ namespace currency
|
|||
int m_daemon_port;
|
||||
bool m_do_refresh_after_load;
|
||||
bool m_do_not_set_date;
|
||||
bool m_print_brain_wallet;
|
||||
bool m_do_pos_mining;
|
||||
bool m_offline_mode;
|
||||
std::string m_restore_wallet;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@
|
|||
#define PROJECT_REVISION "7"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 105
|
||||
#define PROJECT_VERSION_BUILD_NO 110
|
||||
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
|
||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"
|
||||
|
|
|
|||
|
|
@ -400,13 +400,13 @@ namespace plain_wallet
|
|||
return epee::serialization::store_t_to_json(err_result);
|
||||
}
|
||||
|
||||
std::string restore(const std::string& seed, const std::string& path, const std::string& password)
|
||||
std::string restore(const std::string& seed, const std::string& path, const std::string& password, const std::string& seed_password)
|
||||
{
|
||||
GET_INSTANCE_PTR(inst_ptr);
|
||||
|
||||
std::string full_path = get_wallets_folder() + path;
|
||||
epee::json_rpc::response<view::open_wallet_response, epee::json_rpc::dummy_error> ok_response = AUTO_VAL_INIT(ok_response);
|
||||
std::string rsp = inst_ptr->gwm.restore_wallet(epee::string_encoding::convert_to_unicode(full_path), password, seed, ok_response.result);
|
||||
std::string rsp = inst_ptr->gwm.restore_wallet(epee::string_encoding::convert_to_unicode(full_path), password, seed, seed_password, ok_response.result);
|
||||
if (rsp == API_RETURN_CODE_OK || rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
{
|
||||
if (rsp == API_RETURN_CODE_FILE_RESTORED)
|
||||
|
|
@ -526,7 +526,7 @@ namespace plain_wallet
|
|||
}
|
||||
async_callback = [job_id, rwr]()
|
||||
{
|
||||
std::string res = restore(rwr.restore_key, rwr.path, rwr.pass);
|
||||
std::string res = restore(rwr.seed_phrase, rwr.path, rwr.pass, rwr.seed_pass);
|
||||
put_result(job_id, res);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ namespace plain_wallet
|
|||
std::string get_connectivity_status();
|
||||
|
||||
std::string open(const std::string& path, const std::string& password);
|
||||
std::string restore(const std::string& seed, const std::string& path, const std::string& password);
|
||||
std::string restore(const std::string& seed, const std::string& path, const std::string& password, const std::string& seed_password);
|
||||
std::string generate(const std::string& path, const std::string& password);
|
||||
std::string get_opened_wallets();
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,19 @@ public:
|
|||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
struct request_get_smart_wallet_info
|
||||
{
|
||||
uint64_t wallet_id;
|
||||
std::string seed_password;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(wallet_id)
|
||||
KV_SERIALIZE(seed_password)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
struct response_mining_estimate
|
||||
{
|
||||
uint64_t final_amount;
|
||||
|
|
@ -429,16 +442,19 @@ public:
|
|||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
struct restore_wallet_request
|
||||
{
|
||||
std::string pass;
|
||||
std::string seed_pass;
|
||||
std::string path;
|
||||
std::string restore_key;
|
||||
std::string seed_phrase;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(pass)
|
||||
KV_SERIALIZE(path)
|
||||
KV_SERIALIZE(restore_key)
|
||||
KV_SERIALIZE(seed_pass)
|
||||
KV_SERIALIZE(seed_phrase)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
|
@ -548,6 +564,8 @@ public:
|
|||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
typedef tools::wallet_public::seed_info_param seed_info_param;
|
||||
typedef tools::wallet_public::seed_phrase_info seed_phrase_info;
|
||||
|
||||
struct start_backend_params
|
||||
{
|
||||
|
|
@ -587,12 +605,10 @@ public:
|
|||
|
||||
struct get_restore_info_response
|
||||
{
|
||||
std::string restore_key;
|
||||
std::string error_code;
|
||||
std::string seed_phrase;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(restore_key)
|
||||
KV_SERIALIZE(error_code)
|
||||
KV_SERIALIZE(seed_phrase)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2324,6 +2324,8 @@ void wallet2::assign_account(const currency::account_base& acc)
|
|||
clear();
|
||||
m_account = acc;
|
||||
init_log_prefix();
|
||||
if (m_account.is_watch_only())
|
||||
m_watch_only = true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::generate(const std::wstring& path, const std::string& pass, bool auditable_wallet)
|
||||
|
|
@ -2345,7 +2347,7 @@ void wallet2::generate(const std::wstring& path, const std::string& pass, bool a
|
|||
store();
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void wallet2::restore(const std::wstring& path, const std::string& pass, const std::string& seed_or_tracking_seed, bool tracking_wallet)
|
||||
void wallet2::restore(const std::wstring& path, const std::string& pass, const std::string& seed_or_tracking_seed, bool tracking_wallet, const std::string& seed_password)
|
||||
{
|
||||
bool r = false;
|
||||
clear();
|
||||
|
|
@ -2361,7 +2363,7 @@ void wallet2::restore(const std::wstring& path, const std::string& pass, const s
|
|||
}
|
||||
else
|
||||
{
|
||||
r = m_account.restore_from_seed_phrase(seed_or_tracking_seed);
|
||||
r = m_account.restore_from_seed_phrase(seed_or_tracking_seed, seed_password);
|
||||
init_log_prefix();
|
||||
THROW_IF_FALSE_WALLET_EX(r, error::wallet_wrong_seed_error, epee::string_encoding::convert_to_ansii(m_wallet_file));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -470,7 +470,7 @@ namespace tools
|
|||
|
||||
void assign_account(const currency::account_base& acc);
|
||||
void generate(const std::wstring& path, const std::string& password, bool auditable_wallet);
|
||||
void restore(const std::wstring& path, const std::string& pass, const std::string& seed_or_tracking_seed, bool tracking_wallet);
|
||||
void restore(const std::wstring& path, const std::string& pass, const std::string& seed_or_tracking_seed, bool tracking_wallet, const std::string& seed_password);
|
||||
void load(const std::wstring& path, const std::string& password);
|
||||
void store();
|
||||
void store(const std::wstring& path);
|
||||
|
|
|
|||
|
|
@ -23,4 +23,16 @@ namespace tools
|
|||
wi.is_watch_only = w.is_watch_only();
|
||||
return true;
|
||||
}
|
||||
|
||||
inline std::string get_seed_phrase_info(const std::string& seed_phrase, const std::string& seed_password, view::seed_phrase_info& result)
|
||||
{
|
||||
//cut the last timestamp word from restore_dats
|
||||
result.syntax_correct = currency::account_base::is_seed_password_protected(seed_phrase, result.require_password);
|
||||
if (result.syntax_correct)
|
||||
{
|
||||
currency::account_base acc;
|
||||
result.hash_sum_matched = acc.restore_from_seed_phrase(seed_phrase, seed_password);
|
||||
}
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
}
|
||||
|
|
@ -168,6 +168,29 @@ namespace wallet_public
|
|||
};
|
||||
|
||||
|
||||
struct seed_info_param
|
||||
{
|
||||
std::string seed_phrase;
|
||||
std::string seed_password;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(seed_phrase)
|
||||
KV_SERIALIZE(seed_password)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct seed_phrase_info
|
||||
{
|
||||
bool syntax_correct;
|
||||
bool require_password;
|
||||
bool hash_sum_matched;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(syntax_correct)
|
||||
KV_SERIALIZE(require_password)
|
||||
KV_SERIALIZE(hash_sum_matched)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_GET_BALANCE
|
||||
{
|
||||
|
|
@ -221,7 +244,6 @@ namespace wallet_public
|
|||
{
|
||||
std::string address;
|
||||
std::string path;
|
||||
std::string seed;
|
||||
uint64_t transfers_count;
|
||||
uint64_t transfer_entries_count;
|
||||
bool is_whatch_only;
|
||||
|
|
@ -230,7 +252,6 @@ namespace wallet_public
|
|||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(address)
|
||||
KV_SERIALIZE(path)
|
||||
KV_SERIALIZE(seed)
|
||||
KV_SERIALIZE(transfers_count)
|
||||
KV_SERIALIZE(transfer_entries_count)
|
||||
KV_SERIALIZE(is_whatch_only)
|
||||
|
|
@ -239,6 +260,32 @@ namespace wallet_public
|
|||
};
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_GET_WALLET_RESTORE_INFO
|
||||
{
|
||||
struct request
|
||||
{
|
||||
std::string seed_password;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(seed_password)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string seed_phrase;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(seed_phrase)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_GET_SEED_PHRASE_INFO
|
||||
{
|
||||
typedef seed_info_param request;
|
||||
typedef seed_phrase_info response;
|
||||
};
|
||||
|
||||
struct wallet_provision_info
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ using namespace epee;
|
|||
#include "misc_language.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "wallet_rpc_server_error_codes.h"
|
||||
#include "wallet_helpers.h"
|
||||
|
||||
#define WALLET_RPC_BEGIN_TRY_ENTRY() try {
|
||||
#define WALLET_RPC_CATCH_TRY_ENTRY() } \
|
||||
|
|
@ -196,7 +197,6 @@ namespace tools
|
|||
res.path = epee::string_encoding::convert_to_ansii(m_wallet.get_wallet_path());
|
||||
res.transfers_count = m_wallet.get_recent_transfers_total_count();
|
||||
res.transfer_entries_count = m_wallet.get_transfer_entries_count();
|
||||
res.seed = m_wallet.get_account().get_seed_phrase();
|
||||
std::map<uint64_t, uint64_t> distribution;
|
||||
m_wallet.get_utxo_distribution(distribution);
|
||||
for (const auto& ent : distribution)
|
||||
|
|
@ -211,6 +211,25 @@ namespace tools
|
|||
return false;
|
||||
}
|
||||
}
|
||||
bool wallet_rpc_server::on_getwallet_restore_info(const wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO::request& req, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
try
|
||||
{
|
||||
res.seed_phrase = m_wallet.get_account().get_seed_phrase(res.seed_phrase);
|
||||
return true;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
er.message = e.what();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool wallet_rpc_server::on_get_seed_phrase_info(const wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO::request& req, wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
tools::get_seed_phrase_info(req.seed_phrase, req.seed_password, res);
|
||||
return true;
|
||||
}
|
||||
bool wallet_rpc_server::on_get_recent_txs_and_info(const wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::request& req, wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ namespace tools
|
|||
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_public::COMMAND_SIGN_TRANSFER)
|
||||
MAP_JON_RPC_WE("submit_transfer", on_submit_transfer, wallet_public::COMMAND_SUBMIT_TRANSFER)
|
||||
MAP_JON_RPC_WE("search_for_transactions", on_search_for_transactions, wallet_public::COMMAND_RPC_SEARCH_FOR_TRANSACTIONS)
|
||||
MAP_JON_RPC_WE("get_restore_info", on_getwallet_restore_info, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO)
|
||||
MAP_JON_RPC_WE("get_seed_phrase_info", on_get_seed_phrase_info, wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO)
|
||||
//contracts API
|
||||
MAP_JON_RPC_WE("contracts_send_proposal", on_contracts_send_proposal, wallet_public::COMMAND_CONTRACTS_SEND_PROPOSAL)
|
||||
MAP_JON_RPC_WE("contracts_accept_proposal", on_contracts_accept_proposal, wallet_public::COMMAND_CONTRACTS_ACCEPT_PROPOSAL)
|
||||
|
|
@ -70,6 +72,8 @@ namespace tools
|
|||
bool on_getbalance(const wallet_public::COMMAND_RPC_GET_BALANCE::request& req, wallet_public::COMMAND_RPC_GET_BALANCE::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_getaddress(const wallet_public::COMMAND_RPC_GET_ADDRESS::request& req, wallet_public::COMMAND_RPC_GET_ADDRESS::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_getwallet_info(const wallet_public::COMMAND_RPC_GET_WALLET_INFO::request& req, wallet_public::COMMAND_RPC_GET_WALLET_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_getwallet_restore_info(const wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO::request& req, wallet_public::COMMAND_RPC_GET_WALLET_RESTORE_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_get_seed_phrase_info(const wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO::request& req, wallet_public::COMMAND_RPC_GET_SEED_PHRASE_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_get_recent_txs_and_info(const wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::request& req, wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_transfer(const wallet_public::COMMAND_RPC_TRANSFER::request& req, wallet_public::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
bool on_store(const wallet_public::COMMAND_RPC_STORE::request& req, wallet_public::COMMAND_RPC_STORE::response& res, epee::json_rpc::error& er, connection_context& cntx);
|
||||
|
|
|
|||
|
|
@ -911,7 +911,7 @@ std::string wallets_manager::open_wallet(const std::wstring& path, const std::st
|
|||
w->get_unconfirmed_transfers(owr.recent_history.history, exclude_mining_txs);
|
||||
owr.wallet_local_bc_size = w->get_blockchain_current_size();
|
||||
//workaround for missed fee
|
||||
owr.seed = w->get_account().get_seed_phrase();
|
||||
//owr.seed = w->get_account().get_seed_phrase();
|
||||
break;
|
||||
}
|
||||
catch (const tools::error::file_not_found& /**/)
|
||||
|
|
@ -1015,7 +1015,7 @@ std::string wallets_manager::generate_wallet(const std::wstring& path, const std
|
|||
{
|
||||
w->generate(path, password, false);
|
||||
w->set_minimum_height(m_last_daemon_height);
|
||||
owr.seed = w->get_account().get_seed_phrase();
|
||||
//owr.seed = w->get_account().get_seed_phrase();
|
||||
}
|
||||
catch (const tools::error::file_exists&)
|
||||
{
|
||||
|
|
@ -1058,10 +1058,10 @@ std::string wallets_manager::is_pos_allowed()
|
|||
else
|
||||
return API_RETURN_CODE_FALSE;
|
||||
}
|
||||
std::string wallets_manager::is_valid_brain_restore_data(const std::string& seed_phrase)
|
||||
std::string wallets_manager::is_valid_brain_restore_data(const std::string& seed_phrase, const std::string& seed_password)
|
||||
{
|
||||
currency::account_base acc;
|
||||
if (acc.restore_from_seed_phrase(seed_phrase))
|
||||
if (acc.restore_from_seed_phrase(seed_phrase, seed_password))
|
||||
return API_RETURN_CODE_TRUE;
|
||||
|
||||
currency::account_public_address addr;
|
||||
|
|
@ -1081,11 +1081,18 @@ void wallets_manager::subscribe_to_core_events(currency::i_core_event_handler* p
|
|||
|
||||
}
|
||||
#endif
|
||||
|
||||
std::string wallets_manager::get_seed_phrase_info(const std::string& seed_phrase, const std::string& seed_password, view::seed_phrase_info& result)
|
||||
{
|
||||
return tools::get_seed_phrase_info(seed_phrase, seed_password, result);
|
||||
}
|
||||
|
||||
|
||||
void wallets_manager::get_gui_options(view::gui_options& opt)
|
||||
{
|
||||
opt = m_ui_opt;
|
||||
}
|
||||
std::string wallets_manager::restore_wallet(const std::wstring& path, const std::string& password, const std::string& restore_key, view::open_wallet_response& owr)
|
||||
std::string wallets_manager::restore_wallet(const std::wstring& path, const std::string& password, const std::string& seed_phrase, const std::string& seed_password, view::open_wallet_response& owr)
|
||||
{
|
||||
std::shared_ptr<tools::wallet2> w(new tools::wallet2());
|
||||
w->set_use_deffered_global_outputs(m_use_deffered_global_outputs);
|
||||
|
|
@ -1108,9 +1115,9 @@ std::string wallets_manager::restore_wallet(const std::wstring& path, const std:
|
|||
currency::account_base acc;
|
||||
try
|
||||
{
|
||||
bool auditable_watch_only = restore_key.find(':') != std::string::npos;
|
||||
w->restore(path, password, restore_key, auditable_watch_only);
|
||||
owr.seed = w->get_account().get_seed_phrase();
|
||||
bool auditable_watch_only = seed_phrase.find(':') != std::string::npos;
|
||||
w->restore(path, password, seed_phrase, auditable_watch_only, seed_password);
|
||||
//owr.seed = w->get_account().get_seed_phrase();
|
||||
}
|
||||
catch (const tools::error::file_exists&)
|
||||
{
|
||||
|
|
@ -1625,14 +1632,14 @@ std::string wallets_manager::get_mining_history(uint64_t wallet_id, tools::walle
|
|||
wo.w->get()->get_mining_history(mh);
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
std::string wallets_manager::get_wallet_restore_info(uint64_t wallet_id, std::string& restore_key)
|
||||
std::string wallets_manager::get_wallet_restore_info(uint64_t wallet_id, std::string& seed_phrase, const std::string& seed_password)
|
||||
{
|
||||
GET_WALLET_OPT_BY_ID(wallet_id, wo);
|
||||
|
||||
if (wo.wallet_state != view::wallet_status_info::wallet_state_ready || wo.long_refresh_in_progress)
|
||||
return API_RETURN_CODE_CORE_BUSY;
|
||||
|
||||
restore_key = wo.w->get()->get_account().get_seed_phrase();
|
||||
seed_phrase = wo.w->get()->get_account().get_seed_phrase(seed_password);
|
||||
|
||||
return API_RETURN_CODE_OK;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ public:
|
|||
bool get_opened_wallets(std::list<view::open_wallet_response>& result);
|
||||
std::string open_wallet(const std::wstring& path, const std::string& password, uint64_t txs_to_return, view::open_wallet_response& owr, bool exclude_mining_txs = false);
|
||||
std::string generate_wallet(const std::wstring& path, const std::string& password, view::open_wallet_response& owr);
|
||||
std::string restore_wallet(const std::wstring& path, const std::string& password, const std::string& restore_key, view::open_wallet_response& owr);
|
||||
std::string restore_wallet(const std::wstring& path, const std::string& password, const std::string& seed_phrase, const std::string& seed_password, view::open_wallet_response& owr);
|
||||
std::string invoke(uint64_t wallet_id, std::string params);
|
||||
std::string get_wallet_status(uint64_t wallet_id);
|
||||
std::string run_wallet(uint64_t wallet_id);
|
||||
|
|
@ -132,7 +132,7 @@ public:
|
|||
std::string stop_pos_mining(uint64_t wallet_id);
|
||||
std::string check_available_sources(uint64_t wallet_id, std::list<uint64_t>& amounts);
|
||||
std::string get_mining_history(uint64_t wallet_id, tools::wallet_public::mining_history& wrpc);
|
||||
std::string get_wallet_restore_info(uint64_t wallet_id, std::string& restore_key);
|
||||
std::string get_wallet_restore_info(uint64_t wallet_id, std::string& seed_phrase, const std::string& seed_password);
|
||||
std::string backup_wallet(uint64_t wallet_id, const std::wstring& path);
|
||||
std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass);
|
||||
std::string is_wallet_password_valid(uint64_t wallet_id, const std::string& pass);
|
||||
|
|
@ -149,7 +149,8 @@ public:
|
|||
void toggle_pos_mining();
|
||||
std::string transfer(size_t wallet_id, const view::transfer_params& tp, currency::transaction& res_tx);
|
||||
std::string get_config_folder();
|
||||
std::string is_valid_brain_restore_data(const std::string& seed_phrase);
|
||||
std::string is_valid_brain_restore_data(const std::string& seed_phrase, const std::string& seed_password);
|
||||
std::string get_seed_phrase_info(const std::string& seed_phrase, const std::string& seed_password, view::seed_phrase_info& result);
|
||||
#ifndef MOBILE_WALLET_BUILD
|
||||
void subscribe_to_core_events(currency::i_core_event_handler* pevents_handler);
|
||||
//void unsubscribe_to_core_events();
|
||||
|
|
|
|||
|
|
@ -863,6 +863,7 @@ int main(int argc, char* argv[])
|
|||
GENERATE_AND_PLAY(wallet_unconfirmed_tx_expiration);
|
||||
GENERATE_AND_PLAY(wallet_unconfimed_tx_balance);
|
||||
GENERATE_AND_PLAY(packing_outputs_on_pos_minting_wallet);
|
||||
GENERATE_AND_PLAY(wallet_watch_only_and_chain_switch);
|
||||
|
||||
GENERATE_AND_PLAY(wallet_rpc_integrated_address);
|
||||
GENERATE_AND_PLAY(wallet_rpc_integrated_address_transfer);
|
||||
|
|
|
|||
|
|
@ -3441,5 +3441,103 @@ bool wallet_sending_to_integrated_address::c1(currency::core& c, size_t ev_index
|
|||
miner_wlt_2->refresh();
|
||||
CHECK_AND_ASSERT_MES(callback_succeded, false, "callback was not succeded (2)");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
wallet_watch_only_and_chain_switch::wallet_watch_only_and_chain_switch()
|
||||
: m_split_point_block_height(0)
|
||||
{
|
||||
REGISTER_CALLBACK_METHOD(wallet_watch_only_and_chain_switch, c1);
|
||||
}
|
||||
|
||||
bool wallet_watch_only_and_chain_switch::generate(std::vector<test_event_entry>& events) const
|
||||
{
|
||||
bool r = false;
|
||||
|
||||
m_accounts.resize(TOTAL_ACCS_COUNT);
|
||||
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate();
|
||||
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(); alice_acc.make_account_watch_only();
|
||||
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc.generate(true); bob_acc.make_account_watch_only(); // Bob gonna have a tracking wallet
|
||||
|
||||
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
|
||||
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
|
||||
|
||||
|
||||
// 0 10 11 12 13 23 15 <- blockchain height
|
||||
// (0 )- (0r)- (1 )- (2 )- (3 )- (3r)- <- main chain
|
||||
// | tx_0
|
||||
// \ tx_1
|
||||
// \
|
||||
// \- (2a)- (3a)- (3ar)-
|
||||
|
||||
|
||||
MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner_acc);
|
||||
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_acc);
|
||||
|
||||
MAKE_TX_FEE(events, tx_0, miner_acc, alice_acc, MK_TEST_COINS(9), TESTS_DEFAULT_FEE, blk_2);
|
||||
MAKE_TX_FEE(events, tx_1, miner_acc, bob_acc, MK_TEST_COINS(7), TESTS_DEFAULT_FEE, blk_2);
|
||||
|
||||
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2, miner_acc, std::list<transaction>({ tx_0, tx_1 }));
|
||||
|
||||
REWIND_BLOCKS_N(events, blk_3r, blk_3, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
|
||||
|
||||
m_split_point_block_id = get_block_hash(blk_1);
|
||||
m_split_point_block_height = get_block_height(blk_1);
|
||||
|
||||
DO_CALLBACK(events, "c1");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wallet_watch_only_and_chain_switch::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
|
||||
{
|
||||
bool r = false;
|
||||
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
|
||||
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
|
||||
|
||||
// make sure Alice's wallet is watch-only but not a tracking wallet (not auditable)
|
||||
CHECK_AND_ASSERT_MES(alice_wlt->is_watch_only() && !alice_wlt->is_auditable(), false, "incorrect type of Alice's wallet");
|
||||
// make sure Bob's wallet is a tracking wallet
|
||||
CHECK_AND_ASSERT_MES(bob_wlt->is_watch_only() && bob_wlt->is_auditable(), false, "incorrect type of Bob's wallet");
|
||||
|
||||
miner_wlt->refresh();
|
||||
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// check the balances
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, MK_TEST_COINS(9), false, UINT64_MAX, MK_TEST_COINS(9), 0, 0, 0), false, "");
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, MK_TEST_COINS(7), false, UINT64_MAX, MK_TEST_COINS(7), 0, 0, 0), false, "");
|
||||
|
||||
// make a split
|
||||
block out_block;
|
||||
crypto::hash prev_id = m_split_point_block_id;
|
||||
uint64_t current_height = m_split_point_block_height + 1;
|
||||
|
||||
for (size_t i = 0; i < CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 3; ++i)
|
||||
{
|
||||
r = mine_next_pow_block_in_playtime_with_given_txs(m_accounts[MINER_ACC_IDX].get_public_address(), c, std::vector<transaction>(), prev_id, current_height, &out_block);
|
||||
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_block_in_playtime_with_given_txs failed");
|
||||
current_height++;
|
||||
prev_id = get_block_hash(out_block);
|
||||
}
|
||||
|
||||
// make sure the split has happened
|
||||
uint64_t top_height = 0;
|
||||
crypto::hash top_id;
|
||||
c.get_blockchain_top(top_height, top_id);
|
||||
CHECK_AND_ASSERT_MES(top_height == current_height - 1, false, "incorrect top_hegiht = " << top_height);
|
||||
CHECK_AND_ASSERT_MES(top_id == prev_id, false, "incorrect top id = " << top_id);
|
||||
|
||||
// tx_0 and tx_1 should be moved back to the pool
|
||||
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 2, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
|
||||
|
||||
// check the balances, should be zero in actual and few coins in awaiting
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, MK_TEST_COINS(9), false, UINT64_MAX, 0, 0, MK_TEST_COINS(9), 0), false, "");
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, MK_TEST_COINS(7), false, UINT64_MAX, 0, 0, MK_TEST_COINS(7), 0), false, "");
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -265,4 +265,14 @@ struct wallet_sending_to_integrated_address : public wallet_test
|
|||
wallet_sending_to_integrated_address();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
};
|
||||
};
|
||||
|
||||
struct wallet_watch_only_and_chain_switch : public wallet_test
|
||||
{
|
||||
wallet_watch_only_and_chain_switch();
|
||||
bool generate(std::vector<test_event_entry>& events) const;
|
||||
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
|
||||
|
||||
mutable crypto::hash m_split_point_block_id;
|
||||
mutable uint64_t m_split_point_block_height;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -842,7 +842,7 @@ namespace db_test
|
|||
ptr = db_array[4];
|
||||
ASSERT_EQ(ptr->v, "X");
|
||||
|
||||
ASSERT_TRUE(db_array.clear());
|
||||
ASSERT_TRUE((db_array.clear()? true: false));
|
||||
|
||||
db_array.commit_transaction();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,10 @@ TEST(wallet_seed, store_restore_test)
|
|||
{
|
||||
currency::account_base acc;
|
||||
acc.generate();
|
||||
auto seed_phrase = acc.get_seed_phrase();
|
||||
auto seed_phrase = acc.get_seed_phrase("");
|
||||
|
||||
currency::account_base acc2;
|
||||
bool r = acc2.restore_from_seed_phrase(seed_phrase);
|
||||
bool r = acc2.restore_from_seed_phrase(seed_phrase, "");
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
if (memcmp(&acc2.get_keys(), &acc.get_keys(), sizeof(currency::account_keys)))
|
||||
|
|
@ -29,10 +29,10 @@ TEST(wallet_seed, store_restore_test)
|
|||
{
|
||||
currency::account_base acc;
|
||||
acc.generate();
|
||||
auto seed_phrase = acc.get_seed_phrase();
|
||||
auto seed_phrase = acc.get_seed_phrase("");
|
||||
|
||||
currency::account_base acc2;
|
||||
bool r = acc2.restore_from_seed_phrase(seed_phrase);
|
||||
bool r = acc2.restore_from_seed_phrase(seed_phrase, "");
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
if (memcmp(&acc2.get_keys(), &acc.get_keys(), sizeof(currency::account_keys)))
|
||||
|
|
@ -57,7 +57,7 @@ wallet_seed_entry wallet_seed_entries[] =
|
|||
{
|
||||
{
|
||||
// legacy 24-word seed phrase -- invalid
|
||||
"dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew",
|
||||
"dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew god",
|
||||
"",
|
||||
"",
|
||||
0,
|
||||
|
|
@ -66,7 +66,7 @@ wallet_seed_entry wallet_seed_entries[] =
|
|||
},
|
||||
{
|
||||
// old-style 25-word seed phrase -- valid
|
||||
"dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew",
|
||||
"dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew dew god",
|
||||
"5e051454d7226b5734ebd64f754b57db4c655ecda00bd324f1b241d0b6381c0f",
|
||||
"7dde5590fdf430568c00556ac2accf09da6cde9a29a4bc7d1cb6fd267130f006",
|
||||
0,
|
||||
|
|
@ -148,7 +148,41 @@ TEST(wallet_seed, basic_test)
|
|||
bool r = false;
|
||||
try
|
||||
{
|
||||
r = acc.restore_from_seed_phrase(wse.seed_phrase);
|
||||
r = acc.restore_from_seed_phrase(wse.seed_phrase, "");
|
||||
if (r)
|
||||
{
|
||||
for (size_t j = 0; j != 100; j++)
|
||||
{
|
||||
//generate random password
|
||||
std::string pass = epee::string_tools::pod_to_hex(crypto::cn_fast_hash(&j, sizeof(j)));
|
||||
if (j!= 0 && j < 64)
|
||||
{
|
||||
pass.resize(j);
|
||||
}
|
||||
//get secured seed
|
||||
std::string secured_seed = acc.get_seed_phrase(pass);
|
||||
|
||||
//try to restore it without password(should fail)
|
||||
currency::account_base acc2;
|
||||
bool r_fail = acc2.restore_from_seed_phrase(secured_seed, "");
|
||||
ASSERT_EQ(r_fail, false);
|
||||
|
||||
//try to restore it with wrong password
|
||||
bool r_fake_pass = acc2.restore_from_seed_phrase(secured_seed, "fake_password");
|
||||
if (r_fake_pass)
|
||||
{
|
||||
//accidentally checksumm matched(quite possible)
|
||||
ASSERT_EQ(false, acc2.get_keys() == acc.get_keys());
|
||||
}
|
||||
|
||||
//try to restore it from right password
|
||||
currency::account_base acc3;
|
||||
bool r_true_res = acc3.restore_from_seed_phrase(secured_seed, pass);
|
||||
ASSERT_EQ(true, r_true_res);
|
||||
ASSERT_EQ(true, acc3.get_keys() == acc.get_keys());
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue