diff --git a/src/currency_core/account.cpp b/src/currency_core/account.cpp index 675d2f1e..6a07b7c9 100644 --- a/src/currency_core/account.cpp +++ b/src/currency_core/account.cpp @@ -84,11 +84,11 @@ namespace currency } 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()); + std::string timestamp_word = currency::get_word_from_timestamp(m_creation_timestamp, !password.empty()); // floor creation time to WALLET_BRAIN_DATE_QUANTUM to make checksum calculation stable bool self_check_is_password_used = false; - uint64_t creation_timestamp_rounded = get_timstamp_from_word(timestamp_word, self_check_is_password_used); + uint64_t creation_timestamp_rounded = get_timestamp_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 @@ -177,7 +177,7 @@ namespace currency bool has_password = false; try { - m_creation_timestamp = get_timstamp_from_word(timestamp_word, has_password); + m_creation_timestamp = get_timestamp_from_word(timestamp_word, has_password); } catch (...) { @@ -263,7 +263,7 @@ namespace currency return false; } - get_timstamp_from_word(timestamp_word, is_password_protected); + get_timestamp_from_word(timestamp_word, is_password_protected); return true; } diff --git a/src/currency_core/currency_format_utils.cpp b/src/currency_core/currency_format_utils.cpp index d706bc3d..f2ed06d4 100644 --- a/src/currency_core/currency_format_utils.cpp +++ b/src/currency_core/currency_format_utils.cpp @@ -2853,7 +2853,7 @@ namespace currency return reward; } //--------------------------------------------------------------- - std::string get_word_from_timstamp(uint64_t timestamp, bool use_password) + std::string get_word_from_timestamp(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; @@ -2868,7 +2868,7 @@ namespace currency return tools::mnemonic_encoding::word_by_num(weeks_count_32); } //--------------------------------------------------------------- - uint64_t get_timstamp_from_word(std::string word, bool& password_used) + uint64_t get_timestamp_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) diff --git a/src/currency_core/currency_format_utils.h b/src/currency_core/currency_format_utils.h index 3e875c08..78668536 100644 --- a/src/currency_core/currency_format_utils.h +++ b/src/currency_core/currency_format_utils.h @@ -457,9 +457,9 @@ namespace currency 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& gindices); - std::string get_word_from_timstamp(uint64_t timestamp, bool use_password); - uint64_t get_timstamp_from_word(std::string word, bool& password_used, const std::string& buff); - uint64_t get_timstamp_from_word(std::string word, bool& password_used); + std::string get_word_from_timestamp(uint64_t timestamp, bool use_password); + uint64_t get_timestamp_from_word(std::string word, bool& password_used, const std::string& buff); + uint64_t get_timestamp_from_word(std::string word, bool& password_used); bool parse_vote(const std::string& buff, std::list>& votes); std::string generate_origin_for_htlc(const txout_htlc& htlc, const account_keys& acc_keys); diff --git a/tests/unit_tests/wallet_seed_test.cpp b/tests/unit_tests/wallet_seed_test.cpp index efbd2829..cfd6b860 100644 --- a/tests/unit_tests/wallet_seed_test.cpp +++ b/tests/unit_tests/wallet_seed_test.cpp @@ -2,10 +2,13 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include + #include "gtest/gtest.h" #include "include_base_utils.h" #include "currency_core/account.h" +#include "currency_core/currency_format_utils.h" TEST(wallet_seed, store_restore_test) { @@ -211,3 +214,151 @@ TEST(wallet_seed, basic_test) } } + +TEST(wallet_seed, word_from_timestamp) +{ + //timestamp = 0; use_password = false + ASSERT_EQ("like", currency::get_word_from_timestamp(0, false)); + + // timestamp = 0; use_password = true + ASSERT_EQ("among", currency::get_word_from_timestamp(0, true)); + + // timestamp = WALLET_BRAIN_DATE_OFFSET = 1543622400; use_password = false + ASSERT_EQ("like", currency::get_word_from_timestamp(1543622400, false)); + + // timestamp = WALLET_BRAIN_DATE_OFFSET = 1543622400; use_password = true + ASSERT_EQ("among", currency::get_word_from_timestamp(1543622400, true)); + + // timestamp = WALLET_BRAIN_DATE_OFFSET - 1 = 1543622399; use_password = false + ASSERT_EQ("like", currency::get_word_from_timestamp(1543622399, false)); + + // timestamp = WALLET_BRAIN_DATE_OFFSET + 1 = 1543622401; use_password = false + ASSERT_EQ("like", currency::get_word_from_timestamp(1543622401, false)); + + // timestamp = WALLET_BRAIN_DATE_OFFSET + 1 = 1543622401; use_password = true + ASSERT_EQ("among", currency::get_word_from_timestamp(1543622401, true)); + + /* + Values get_word_from_timestamp(1, true), + get_word_from_timestamp(1543622401, true) must be equal. + */ + + ASSERT_EQ("among", currency::get_word_from_timestamp(1, true)); + ASSERT_EQ(currency::get_word_from_timestamp(1, true), + currency::get_word_from_timestamp(1543622401, true)); + + /* + 2027462399 is the largest timestamp argument value under which the + inequality weeks_count < WALLET_BRAIN_DATE_MAX_WEEKS_COUNT is satisfied. + + timestamp = 2027462399 + date_offset = timestamp - WALLET_BRAIN_DATE_OFFSET = 483839999 + weeks_count = date_offset / WALLET_BRAIN_DATE_QUANTUM = 799 + WALLET_BRAIN_DATE_MAX_WEEKS_COUNT = 800 + WALLET_BRAIN_DATE_QUANTUM = 604800 + + floor(483839999 / 604800) = 799 + floor(483840000 / 604800) = 800 + */ + + // weeks_count_32 = 799; wordsArray[799] = "ugly" + ASSERT_EQ("ugly", currency::get_word_from_timestamp(2027462399, false)); + + // weeks_count_32 = 799 + 800 = 1599; wordsArray[1599] = "moan" + ASSERT_EQ("moan", currency::get_word_from_timestamp(2027462399, true)); + + /* + If you pass values ​​>= 2027462399 + 1, then the inequality + weeks_count < WALLET_BRAIN_DATE_MAX_WEEKS_COUNT is not satisfied. The + function throws an exception. + */ + + EXPECT_THROW(currency::get_word_from_timestamp(2027462400, false), + std::runtime_error); + + EXPECT_THROW(currency::get_word_from_timestamp(2027462400, true), + std::runtime_error); +} + +TEST(wallet_seed, timestamp_from_word) +{ + { + // WALLET_BRAIN_DATE_OFFSET = 1543622400 + + { + bool password_used{false}; + + ASSERT_EQ(1543622400, + currency::get_timestamp_from_word("like", password_used)); + ASSERT_FALSE(password_used); + } + + { + bool password_used{true}; + + ASSERT_EQ(1543622400, + currency::get_timestamp_from_word("like", password_used)); + ASSERT_FALSE(password_used); + } + } + + { + // WALLET_BRAIN_DATE_OFFSET = 1543622400 + + { + bool password_used{true}; + + ASSERT_EQ(1543622400, + currency::get_timestamp_from_word("among", password_used)); + ASSERT_TRUE(password_used); + } + + { + bool password_used{false}; + + ASSERT_EQ(1543622400, + currency::get_timestamp_from_word("among", password_used)); + ASSERT_TRUE(password_used); + } + } + + { + // (1625 - 800) * 604800 + 1543622400 = 2042582400 + + { + bool password_used{false}; + + ASSERT_EQ(2026857600, + currency::get_timestamp_from_word("ugly", password_used)); + ASSERT_FALSE(password_used); + } + + { + bool password_used{true}; + + ASSERT_EQ(2026857600, + currency::get_timestamp_from_word("ugly", password_used)); + ASSERT_FALSE(password_used); + } + } + + { + // (1625 - 800) * 604800 + 1543622400 = 2042582400 + + { + bool password_used{false}; + + ASSERT_EQ(2042582400, + currency::get_timestamp_from_word("weary", password_used)); + ASSERT_TRUE(password_used); + } + + { + bool password_used{true}; + + ASSERT_EQ(2042582400, + currency::get_timestamp_from_word("weary", password_used)); + ASSERT_TRUE(password_used); + } + } +}