diff options
-rw-r--r-- | .gitignore | 4 | ||||
-rw-r--r-- | contrib/epee/include/console_handler.h | 8 | ||||
-rw-r--r-- | src/common/command_line.cpp | 12 | ||||
-rw-r--r-- | src/common/command_line.h | 3 | ||||
-rw-r--r-- | src/common/pod-class.h | 6 | ||||
-rw-r--r-- | src/crypto/crypto.cpp | 25 | ||||
-rw-r--r-- | src/crypto/crypto.h | 8 | ||||
-rw-r--r-- | src/crypto/electrum-words.cpp | 110 | ||||
-rw-r--r-- | src/crypto/electrum-words.h | 3280 | ||||
-rw-r--r-- | src/cryptonote_config.h | 2 | ||||
-rw-r--r-- | src/cryptonote_core/account.cpp | 16 | ||||
-rw-r--r-- | src/cryptonote_core/account.h | 2 | ||||
-rw-r--r-- | src/cryptonote_core/checkpoints_create.h | 1 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 13 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.h | 1 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.cpp | 26 | ||||
-rw-r--r-- | src/cryptonote_core/tx_pool.h | 8 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 9 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_error_codes.h | 3 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 112 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.h | 9 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 7 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 3 | ||||
-rw-r--r-- | src/wallet/wallet_errors.h | 11 |
24 files changed, 3638 insertions, 41 deletions
diff --git a/.gitignore b/.gitignore index 20a3894a6..527864624 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ .DS_Store /build /tags + +# vim swap files +*.swp +*.swo diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/console_handler.h index 356ee7f9a..ab3cf67c6 100644 --- a/contrib/epee/include/console_handler.h +++ b/contrib/epee/include/console_handler.h @@ -233,6 +233,7 @@ namespace epee void stop() { + m_running = false; m_stdin_reader.stop(); } @@ -244,6 +245,10 @@ namespace epee bool continue_handle = true; while(continue_handle) { + if (!m_running) + { + break; + } if (!prompt.empty()) { epee::log_space::set_console_color(epee::log_space::console_color_yellow, true); @@ -257,7 +262,7 @@ namespace epee std::string command; if(!m_stdin_reader.get_line(command)) { - LOG_PRINT("Failed to read line. Ignoring and continuing to run, exiting daemon may require a SIGTERM kill.", LOG_LEVEL_0); + LOG_PRINT("Failed to read line.", LOG_LEVEL_0); } string_tools::trim(command); @@ -285,6 +290,7 @@ namespace epee private: async_stdin_reader m_stdin_reader; + bool m_running = true; }; diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index 0b90345d9..d507f36a7 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -3,9 +3,21 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include "command_line.h" +#include "string_tools.h" namespace command_line { + std::string input_line(const std::string& prompt) + { + std::cout << prompt; + + std::string buf; + std::getline(std::cin, buf); + + return epee::string_tools::trim(buf); + + } + const arg_descriptor<bool> arg_help = {"help", "Produce help message"}; const arg_descriptor<bool> arg_version = {"version", "Output version information"}; const arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory"}; diff --git a/src/common/command_line.h b/src/common/command_line.h index 860653772..a6f78569c 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -14,6 +14,9 @@ namespace command_line { + + std::string input_line(const std::string& prompt); + template<typename T, bool required = false> struct arg_descriptor; diff --git a/src/common/pod-class.h b/src/common/pod-class.h index c07edb208..10d680484 100644 --- a/src/common/pod-class.h +++ b/src/common/pod-class.h @@ -4,8 +4,14 @@ #pragma once +// FIXME: Why is this ifdef needed? Hopefully making it struct won't break things. + +/* #if defined(_MSC_VER) #define POD_CLASS struct #else #define POD_CLASS class #endif +*/ + +#define POD_CLASS struct diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index f5f525700..98a17a3e4 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -50,6 +50,7 @@ namespace crypto { return &reinterpret_cast<const unsigned char &>(scalar); } + /* generate a random 32-byte (256-bit) integer and copy it to res */ static inline void random_scalar(ec_scalar &res) { unsigned char tmp[64]; generate_random_bytes(64, tmp); @@ -62,12 +63,32 @@ namespace crypto { sc_reduce32(&res); } - void crypto_ops::generate_keys(public_key &pub, secret_key &sec) { + /* + * generate public and secret keys from a random 256-bit integer + * TODO: allow specifiying random value (for wallet recovery) + * + */ + secret_key crypto_ops::generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover) { lock_guard<mutex> lock(random_lock); ge_p3 point; - random_scalar(sec); + + secret_key rng; + + if (recover) + { + rng = recovery_key; + } + else + { + random_scalar(rng); + } + sec = rng; + sc_reduce32(&sec); // reduce in case second round of keys (sendkeys) + ge_scalarmult_base(&point, &sec); ge_p3_tobytes(&pub, &point); + + return rng; } bool crypto_ops::check_key(const public_key &key) { diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 61641fbcf..024713df1 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -62,8 +62,8 @@ namespace crypto { void operator=(const crypto_ops &); ~crypto_ops(); - static void generate_keys(public_key &, secret_key &); - friend void generate_keys(public_key &, secret_key &); + static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false); + friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover); static bool check_key(const public_key &); friend bool check_key(const public_key &); static bool secret_key_to_public_key(const secret_key &, public_key &); @@ -102,8 +102,8 @@ namespace crypto { /* Generate a new key pair */ - inline void generate_keys(public_key &pub, secret_key &sec) { - crypto_ops::generate_keys(pub, sec); + inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) { + return crypto_ops::generate_keys(pub, sec, recovery_key, recover); } /* Check a public key. Returns true if it is valid, false otherwise. diff --git a/src/crypto/electrum-words.cpp b/src/crypto/electrum-words.cpp new file mode 100644 index 000000000..96a392d04 --- /dev/null +++ b/src/crypto/electrum-words.cpp @@ -0,0 +1,110 @@ +/* + * This file and its header file are for translating Electrum-style word lists + * into their equivalent byte representations for cross-compatibility with + * that method of "backing up" one's wallet keys. + */ + +#include <string> +#include <cassert> +#include <map> +#include <cstdint> +#include <vector> +#include <boost/algorithm/string.hpp> +#include "crypto/crypto.h" // for declaration of crypto::secret_key + +#include "crypto/electrum-words.h" + +namespace crypto +{ + namespace ElectrumWords + { + + /* convert words to bytes, 3 words -> 4 bytes + * returns: + * false if not a multiple of 3 words, or if a words is not in the + * words list + * + * true otherwise + */ + bool words_to_bytes(const std::string& words, crypto::secret_key& dst) + { + int n = NUMWORDS; // hardcoded because this is what electrum uses + + std::vector<std::string> wlist; + + boost::split(wlist, words, boost::is_any_of(" ")); + + // error on non-compliant word list + if (wlist.size() != 12 && wlist.size() != 24) return false; + + for (unsigned int i=0; i < wlist.size() / 3; i++) + { + uint32_t val; + uint32_t w1, w2, w3; + + // verify all three words exist in the word list + if (wordsMap.count(wlist[i*3]) == 0 || + wordsMap.count(wlist[i*3 + 1]) == 0 || + wordsMap.count(wlist[i*3 + 2]) == 0) + { + return false; + } + + w1 = wordsMap.at(wlist[i*3]); + w2 = wordsMap.at(wlist[i*3 + 1]); + w3 = wordsMap.at(wlist[i*3 + 2]); + + val = w1 + n * (((n - w1) + w2) % n) + n * n * (((n - w2) + w3) % n); + + if (!(val % n == w1)) return false; + + memcpy(dst.data + i * 4, &val, 4); // copy 4 bytes to position + } + + std::string wlist_copy = words; + if (wlist.size() == 12) + { + memcpy(dst.data, dst.data + 16, 16); // if electrum 12-word seed, duplicate + wlist_copy += ' '; + wlist_copy += words; + } + + return true; + } + + /* convert bytes to words, 4 bytes-> 3 words + * returns: + * false if wrong number of bytes (shouldn't be possible) + * true otherwise + */ + bool bytes_to_words(const crypto::secret_key& src, std::string& words) + { + int n = NUMWORDS; // hardcoded because this is what electrum uses + + if (sizeof(src.data) % 4 != 0) return false; + + // 8 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626 + for (unsigned int i=0; i < sizeof(src.data)/4; i++, words += ' ') + { + uint32_t w1, w2, w3; + + uint32_t val; + + memcpy(&val, (src.data) + (i * 4), 4); + + w1 = val % n; + w2 = ((val / n) + w1) % n; + w3 = (((val / n) / n) + w2) % n; + + words += wordsArray[w1]; + words += ' '; + words += wordsArray[w2]; + words += ' '; + words += wordsArray[w3]; + } + return false; + } + + } // namespace ElectrumWords + +} // namespace crypto diff --git a/src/crypto/electrum-words.h b/src/crypto/electrum-words.h new file mode 100644 index 000000000..a533299bd --- /dev/null +++ b/src/crypto/electrum-words.h @@ -0,0 +1,3280 @@ +/* + * This file and its cpp file are for translating Electrum-style word lists + * into their equivalent byte representations for cross-compatibility with + * that method of "backing up" one's wallet keys. + */ + +#include <string> +#include <cstdint> +#include <map> +#include "crypto/crypto.h" // for declaration of crypto::secret_key + +namespace crypto +{ + namespace ElectrumWords + { + + const int NUMWORDS = 1626; + + bool words_to_bytes(const std::string& words, crypto::secret_key& dst); + bool bytes_to_words(const crypto::secret_key& src, std::string& words); + + const std::map<std::string,uint32_t> wordsMap = { + {"like", 0}, + {"just", 1}, + {"love", 2}, + {"know", 3}, + {"never", 4}, + {"want", 5}, + {"time", 6}, + {"out", 7}, + {"there", 8}, + {"make", 9}, + {"look", 10}, + {"eye", 11}, + {"down", 12}, + {"only", 13}, + {"think", 14}, + {"heart", 15}, + {"back", 16}, + {"then", 17}, + {"into", 18}, + {"about", 19}, + {"more", 20}, + {"away", 21}, + {"still", 22}, + {"them", 23}, + {"take", 24}, + {"thing", 25}, + {"even", 26}, + {"through", 27}, + {"long", 28}, + {"always", 29}, + {"world", 30}, + {"too", 31}, + {"friend", 32}, + {"tell", 33}, + {"try", 34}, + {"hand", 35}, + {"thought", 36}, + {"over", 37}, + {"here", 38}, + {"other", 39}, + {"need", 40}, + {"smile", 41}, + {"again", 42}, + {"much", 43}, + {"cry", 44}, + {"been", 45}, + {"night", 46}, + {"ever", 47}, + {"little", 48}, + {"said", 49}, + {"end", 50}, + {"some", 51}, + {"those", 52}, + {"around", 53}, + {"mind", 54}, + {"people", 55}, + {"girl", 56}, + {"leave", 57}, + {"dream", 58}, + {"left", 59}, + {"turn", 60}, + {"myself", 61}, + {"give", 62}, + {"nothing", 63}, + {"really", 64}, + {"off", 65}, + {"before", 66}, + {"something", 67}, + {"find", 68}, + {"walk", 69}, + {"wish", 70}, + {"good", 71}, + {"once", 72}, + {"place", 73}, + {"ask", 74}, + {"stop", 75}, + {"keep", 76}, + {"watch", 77}, + {"seem", 78}, + {"everything", 79}, + {"wait", 80}, + {"got", 81}, + {"yet", 82}, + {"made", 83}, + {"remember", 84}, + {"start", 85}, + {"alone", 86}, + {"run", 87}, + {"hope", 88}, + {"maybe", 89}, + {"believe", 90}, + {"body", 91}, + {"hate", 92}, + {"after", 93}, + {"close", 94}, + {"talk", 95}, + {"stand", 96}, + {"own", 97}, + {"each", 98}, + {"hurt", 99}, + {"help", 100}, + {"home", 101}, + {"god", 102}, + {"soul", 103}, + {"new", 104}, + {"many", 105}, + {"two", 106}, + {"inside", 107}, + {"should", 108}, + {"true", 109}, + {"first", 110}, + {"fear", 111}, + {"mean", 112}, + {"better", 113}, + {"play", 114}, + {"another", 115}, + {"gone", 116}, + {"change", 117}, + {"use", 118}, + {"wonder", 119}, + {"someone", 120}, + {"hair", 121}, + {"cold", 122}, + {"open", 123}, + {"best", 124}, + {"any", 125}, + {"behind", 126}, + {"happen", 127}, + {"water", 128}, + {"dark", 129}, + {"laugh", 130}, + {"stay", 131}, + {"forever", 132}, + {"name", 133}, + {"work", 134}, + {"show", 135}, + {"sky", 136}, + {"break", 137}, + {"came", 138}, + {"deep", 139}, + {"door", 140}, + {"put", 141}, + {"black", 142}, + {"together", 143}, + {"upon", 144}, + {"happy", 145}, + {"such", 146}, + {"great", 147}, + {"white", 148}, + {"matter", 149}, + {"fill", 150}, + {"past", 151}, + {"please", 152}, + {"burn", 153}, + {"cause", 154}, + {"enough", 155}, + {"touch", 156}, + {"moment", 157}, + {"soon", 158}, + {"voice", 159}, + {"scream", 160}, + {"anything", 161}, + {"stare", 162}, + {"sound", 163}, + {"red", 164}, + {"everyone", 165}, + {"hide", 166}, + {"kiss", 167}, + {"truth", 168}, + {"death", 169}, + {"beautiful", 170}, + {"mine", 171}, + {"blood", 172}, + {"broken", 173}, + {"very", 174}, + {"pass", 175}, + {"next", 176}, + {"forget", 177}, + {"tree", 178}, + {"wrong", 179}, + {"air", 180}, + {"mother", 181}, + {"understand", 182}, + {"lip", 183}, + {"hit", 184}, + {"wall", 185}, + {"memory", 186}, + {"sleep", 187}, + {"free", 188}, + {"high", 189}, + {"realize", 190}, + {"school", 191}, + {"might", 192}, + {"skin", 193}, + {"sweet", 194}, + {"perfect", 195}, + {"blue", 196}, + {"kill", 197}, + {"breath", 198}, + {"dance", 199}, + {"against", 200}, + {"fly", 201}, + {"between", 202}, + {"grow", 203}, + {"strong", 204}, + {"under", 205}, + {"listen", 206}, + {"bring", 207}, + {"sometimes", 208}, + {"speak", 209}, + {"pull", 210}, + {"person", 211}, + {"become", 212}, + {"family", 213}, + {"begin", 214}, + {"ground", 215}, + {"real", 216}, + {"small", 217}, + {"father", 218}, + {"sure", 219}, + {"feet", 220}, + {"rest", 221}, + {"young", 222}, + {"finally", 223}, + {"land", 224}, + {"across", 225}, + {"today", 226}, + {"different", 227}, + {"guy", 228}, + {"line", 229}, + {"fire", 230}, + {"reason", 231}, + {"reach", 232}, + {"second", 233}, + {"slowly", 234}, + {"write", 235}, + {"eat", 236}, + {"smell", 237}, + {"mouth", 238}, + {"step", 239}, + {"learn", 240}, + {"three", 241}, + {"floor", 242}, + {"promise", 243}, + {"breathe", 244}, + {"darkness", 245}, + {"push", 246}, + {"earth", 247}, + {"guess", 248}, + {"save", 249}, + {"song", 250}, + {"above", 251}, + {"along", 252}, + {"both", 253}, + {"color", 254}, + {"house", 255}, + {"almost", 256}, + {"sorry", 257}, + {"anymore", 258}, + {"brother", 259}, + {"okay", 260}, + {"dear", 261}, + {"game", 262}, + {"fade", 263}, + {"already", 264}, + {"apart", 265}, + {"warm", 266}, + {"beauty", 267}, + {"heard", 268}, + {"notice", 269}, + {"question", 270}, + {"shine", 271}, + {"began", 272}, + {"piece", 273}, + {"whole", 274}, + {"shadow", 275}, + {"secret", 276}, + {"street", 277}, + {"within", 278}, + {"finger", 279}, + {"point", 280}, + {"morning", 281}, + {"whisper", 282}, + {"child", 283}, + {"moon", 284}, + {"green", 285}, + {"story", 286}, + {"glass", 287}, + {"kid", 288}, + {"silence", 289}, + {"since", 290}, + {"soft", 291}, + {"yourself", 292}, + {"empty", 293}, + {"shall", 294}, + {"angel", 295}, + {"answer", 296}, + {"baby", 297}, + {"bright", 298}, + {"dad", 299}, + {"path", 300}, + {"worry", 301}, + {"hour", 302}, + {"drop", 303}, + {"follow", 304}, + {"power", 305}, + {"war", 306}, + {"half", 307}, + {"flow", 308}, + {"heaven", 309}, + {"act", 310}, + {"chance", 311}, + {"fact", 312}, + {"least", 313}, + {"tired", 314}, + {"children", 315}, + {"near", 316}, + {"quite", 317}, + {"afraid", 318}, + {"rise", 319}, + {"sea", 320}, + {"taste", 321}, + {"window", 322}, + {"cover", 323}, + {"nice", 324}, + {"trust", 325}, + {"lot", 326}, + {"sad", 327}, + {"cool", 328}, + {"force", 329}, + {"peace", 330}, + {"return", 331}, + {"blind", 332}, + {"easy", 333}, + {"ready", 334}, + {"roll", 335}, + {"rose", 336}, + {"drive", 337}, + {"held", 338}, + {"music", 339}, + {"beneath", 340}, + {"hang", 341}, + {"mom", 342}, + {"paint", 343}, + {"emotion", 344}, + {"quiet", 345}, + {"clear", 346}, + {"cloud", 347}, + {"few", 348}, + {"pretty", 349}, + {"bird", 350}, + {"outside", 351}, + {"paper", 352}, + {"picture", 353}, + {"front", 354}, + {"rock", 355}, + {"simple", 356}, + {"anyone", 357}, + {"meant", 358}, + {"reality", 359}, + {"road", 360}, + {"sense", 361}, + {"waste", 362}, + {"bit", 363}, + {"leaf", 364}, + {"thank", 365}, + {"happiness", 366}, + {"meet", 367}, + {"men", 368}, + {"smoke", 369}, + {"truly", 370}, + {"decide", 371}, + {"self", 372}, + {"age", 373}, + {"book", 374}, + {"form", 375}, + {"alive", 376}, + {"carry", 377}, + {"escape", 378}, + {"damn", 379}, + {"instead", 380}, + {"able", 381}, + {"ice", 382}, + {"minute", 383}, + {"throw", 384}, + {"catch", 385}, + {"leg", 386}, + {"ring", 387}, + {"course", 388}, + {"goodbye", 389}, + {"lead", 390}, + {"poem", 391}, + {"sick", 392}, + {"corner", 393}, + {"desire", 394}, + {"known", 395}, + {"problem", 396}, + {"remind", 397}, + {"shoulder", 398}, + {"suppose", 399}, + {"toward", 400}, + {"wave", 401}, + {"drink", 402}, + {"jump", 403}, + {"woman", 404}, + {"pretend", 405}, + {"sister", 406}, + {"week", 407}, + {"human", 408}, + {"joy", 409}, + {"crack", 410}, + {"grey", 411}, + {"pray", 412}, + {"surprise", 413}, + {"dry", 414}, + {"knee", 415}, + {"less", 416}, + {"search", 417}, + {"bleed", 418}, + {"caught", 419}, + {"clean", 420}, + {"embrace", 421}, + {"future", 422}, + {"king", 423}, + {"son", 424}, + {"sorrow", 425}, + {"chest", 426}, + {"hug", 427}, + {"remain", 428}, + {"sat", 429}, + {"worth", 430}, + {"blow", 431}, + {"daddy", 432}, + {"final", 433}, + {"parent", 434}, + {"tight", 435}, + {"also", 436}, + {"create", 437}, + {"lonely", 438}, + {"safe", 439}, + {"cross", 440}, + {"dress", 441}, + {"evil", 442}, + {"silent", 443}, + {"bone", 444}, + {"fate", 445}, + {"perhaps", 446}, + {"anger", 447}, + {"class", 448}, + {"scar", 449}, + {"snow", 450}, + {"tiny", 451}, + {"tonight", 452}, + {"continue", 453}, + {"control", 454}, + {"dog", 455}, + {"edge", 456}, + {"mirror", 457}, + {"month", 458}, + {"suddenly", 459}, + {"comfort", 460}, + {"given", 461}, + {"loud", 462}, + {"quickly", 463}, + {"gaze", 464}, + {"plan", 465}, + {"rush", 466}, + {"stone", 467}, + {"town", 468}, + {"battle", 469}, + {"ignore", 470}, + {"spirit", 471}, + {"stood", 472}, + {"stupid", 473}, + {"yours", 474}, + {"brown", 475}, + {"build", 476}, + {"dust", 477}, + {"hey", 478}, + {"kept", 479}, + {"pay", 480}, + {"phone", 481}, + {"twist", 482}, + {"although", 483}, + {"ball", 484}, + {"beyond", 485}, + {"hidden", 486}, + {"nose", 487}, + {"taken", 488}, + {"fail", 489}, + {"float", 490}, + {"pure", 491}, + {"somehow", 492}, + {"wash", 493}, + {"wrap", 494}, + {"angry", 495}, + {"cheek", 496}, + {"creature", 497}, + {"forgotten", 498}, + {"heat", 499}, + {"rip", 500}, + {"single", 501}, + {"space", 502}, + {"special", 503}, + {"weak", 504}, + {"whatever", 505}, + {"yell", 506}, + {"anyway", 507}, + {"blame", 508}, + {"job", 509}, + {"choose", 510}, + {"country", 511}, + {"curse", 512}, + {"drift", 513}, + {"echo", 514}, + {"figure", 515}, + {"grew", 516}, + {"laughter", 517}, + {"neck", 518}, + {"suffer", 519}, + {"worse", 520}, + {"yeah", 521}, + {"disappear", 522}, + {"foot", 523}, + {"forward", 524}, + {"knife", 525}, + {"mess", 526}, + {"somewhere", 527}, + {"stomach", 528}, + {"storm", 529}, + {"beg", 530}, + {"idea", 531}, + {"lift", 532}, + {"offer", 533}, + {"breeze", 534}, + {"field", 535}, + {"five", 536}, + {"often", 537}, + {"simply", 538}, + {"stuck", 539}, + {"win", 540}, + {"allow", 541}, + {"confuse", 542}, + {"enjoy", 543}, + {"except", 544}, + {"flower", 545}, + {"seek", 546}, + {"strength", 547}, + {"calm", 548}, + {"grin", 549}, + {"gun", 550}, + {"heavy", 551}, + {"hill", 552}, + {"large", 553}, + {"ocean", 554}, + {"shoe", 555}, + {"sigh", 556}, + {"straight", 557}, + {"summer", 558}, + {"tongue", 559}, + {"accept", 560}, + {"crazy", 561}, + {"everyday", 562}, + {"exist", 563}, + {"grass", 564}, + {"mistake", 565}, + {"sent", 566}, + {"shut", 567}, + {"surround", 568}, + {"table", 569}, + {"ache", 570}, + {"brain", 571}, + {"destroy", 572}, + {"heal", 573}, + {"nature", 574}, + {"shout", 575}, + {"sign", 576}, + {"stain", 577}, + {"choice", 578}, + {"doubt", 579}, + {"glance", 580}, + {"glow", 581}, + {"mountain", 582}, + {"queen", 583}, + {"stranger", 584}, + {"throat", 585}, + {"tomorrow", 586}, + {"city", 587}, + {"either", 588}, + {"fish", 589}, + {"flame", 590}, + {"rather", 591}, + {"shape", 592}, + {"spin", 593}, + {"spread", 594}, + {"ash", 595}, + {"distance", 596}, + {"finish", 597}, + {"image", 598}, + {"imagine", 599}, + {"important", 600}, + {"nobody", 601}, + {"shatter", 602}, + {"warmth", 603}, + {"became", 604}, + {"feed", 605}, + {"flesh", 606}, + {"funny", 607}, + {"lust", 608}, + {"shirt", 609}, + {"trouble", 610}, + {"yellow", 611}, + {"attention", 612}, + {"bare", 613}, + {"bite", 614}, + {"money", 615}, + {"protect", 616}, + {"amaze", 617}, + {"appear", 618}, + {"born", 619}, + {"choke", 620}, + {"completely", 621}, + {"daughter", 622}, + {"fresh", 623}, + {"friendship", 624}, + {"gentle", 625}, + {"probably", 626}, + {"six", 627}, + {"deserve", 628}, + {"expect", 629}, + {"grab", 630}, + {"middle", 631}, + {"nightmare", 632}, + {"river", 633}, + {"thousand", 634}, + {"weight", 635}, + {"worst", 636}, + {"wound", 637}, + {"barely", 638}, + {"bottle", 639}, + {"cream", 640}, + {"regret", 641}, + {"relationship", 642}, + {"stick", 643}, + {"test", 644}, + {"crush", 645}, + {"endless", 646}, + {"fault", 647}, + {"itself", 648}, + {"rule", 649}, + {"spill", 650}, + {"art", 651}, + {"circle", 652}, + {"join", 653}, + {"kick", 654}, + {"mask", 655}, + {"master", 656}, + {"passion", 657}, + {"quick", 658}, + {"raise", 659}, + {"smooth", 660}, + {"unless", 661}, + {"wander", 662}, + {"actually", 663}, + {"broke", 664}, + {"chair", 665}, + {"deal", 666}, + {"favorite", 667}, + {"gift", 668}, + {"note", 669}, + {"number", 670}, + {"sweat", 671}, + {"box", 672}, + {"chill", 673}, + {"clothes", 674}, + {"lady", 675}, + {"mark", 676}, + {"park", 677}, + {"poor", 678}, + {"sadness", 679}, + {"tie", 680}, + {"animal", 681}, + {"belong", 682}, + {"brush", 683}, + {"consume", 684}, + {"dawn", 685}, + {"forest", 686}, + {"innocent", 687}, + {"pen", 688}, + {"pride", 689}, + {"stream", 690}, + {"thick", 691}, + {"clay", 692}, + {"complete", 693}, + {"count", 694}, + {"draw", 695}, + {"faith", 696}, + {"press", 697}, + {"silver", 698}, + {"struggle", 699}, + {"surface", 700}, + {"taught", 701}, + {"teach", 702}, + {"wet", 703}, + {"bless", 704}, + {"chase", 705}, + {"climb", 706}, + {"enter", 707}, + {"letter", 708}, + {"melt", 709}, + {"metal", 710}, + {"movie", 711}, + {"stretch", 712}, + {"swing", 713}, + {"vision", 714}, + {"wife", 715}, + {"beside", 716}, + {"crash", 717}, + {"forgot", 718}, + {"guide", 719}, + {"haunt", 720}, + {"joke", 721}, + {"knock", 722}, + {"plant", 723}, + {"pour", 724}, + {"prove", 725}, + {"reveal", 726}, + {"steal", 727}, + {"stuff", 728}, + {"trip", 729}, + {"wood", 730}, + {"wrist", 731}, + {"bother", 732}, + {"bottom", 733}, + {"crawl", 734}, + {"crowd", 735}, + {"fix", 736}, + {"forgive", 737}, + {"frown", 738}, + {"grace", 739}, + {"loose", 740}, + {"lucky", 741}, + {"party", 742}, + {"release", 743}, + {"surely", 744}, + {"survive", 745}, + {"teacher", 746}, + {"gently", 747}, + {"grip", 748}, + {"speed", 749}, + {"suicide", 750}, + {"travel", 751}, + {"treat", 752}, + {"vein", 753}, + {"written", 754}, + {"cage", 755}, + {"chain", 756}, + {"conversation", 757}, + {"date", 758}, + {"enemy", 759}, + {"however", 760}, + {"interest", 761}, + {"million", 762}, + {"page", 763}, + {"pink", 764}, + {"proud", 765}, + {"sway", 766}, + {"themselves", 767}, + {"winter", 768}, + {"church", 769}, + {"cruel", 770}, + {"cup", 771}, + {"demon", 772}, + {"experience", 773}, + {"freedom", 774}, + {"pair", 775}, + {"pop", 776}, + {"purpose", 777}, + {"respect", 778}, + {"shoot", 779}, + {"softly", 780}, + {"state", 781}, + {"strange", 782}, + {"bar", 783}, + {"birth", 784}, + {"curl", 785}, + {"dirt", 786}, + {"excuse", 787}, + {"lord", 788}, + {"lovely", 789}, + {"monster", 790}, + {"order", 791}, + {"pack", 792}, + {"pants", 793}, + {"pool", 794}, + {"scene", 795}, + {"seven", 796}, + {"shame", 797}, + {"slide", 798}, + {"ugly", 799}, + {"among", 800}, + {"blade", 801}, + {"blonde", 802}, + {"closet", 803}, + {"creek", 804}, + {"deny", 805}, + {"drug", 806}, + {"eternity", 807}, + {"gain", 808}, + {"grade", 809}, + {"handle", 810}, + {"key", 811}, + {"linger", 812}, + {"pale", 813}, + {"prepare", 814}, + {"swallow", 815}, + {"swim", 816}, + {"tremble", 817}, + {"wheel", 818}, + {"won", 819}, + {"cast", 820}, + {"cigarette", 821}, + {"claim", 822}, + {"college", 823}, + {"direction", 824}, + {"dirty", 825}, + {"gather", 826}, + {"ghost", 827}, + {"hundred", 828}, + {"loss", 829}, + {"lung", 830}, + {"orange", 831}, + {"present", 832}, + {"swear", 833}, + {"swirl", 834}, + {"twice", 835}, + {"wild", 836}, + {"bitter", 837}, + {"blanket", 838}, + {"doctor", 839}, + {"everywhere", 840}, + {"flash", 841}, + {"grown", 842}, + {"knowledge", 843}, + {"numb", 844}, + {"pressure", 845}, + {"radio", 846}, + {"repeat", 847}, + {"ruin", 848}, + {"spend", 849}, + {"unknown", 850}, + {"buy", 851}, + {"clock", 852}, + {"devil", 853}, + {"early", 854}, + {"false", 855}, + {"fantasy", 856}, + {"pound", 857}, + {"precious", 858}, + {"refuse", 859}, + {"sheet", 860}, + {"teeth", 861}, + {"welcome", 862}, + {"add", 863}, + {"ahead", 864}, + {"block", 865}, + {"bury", 866}, + {"caress", 867}, + {"content", 868}, + {"depth", 869}, + {"despite", 870}, + {"distant", 871}, + {"marry", 872}, + {"purple", 873}, + {"threw", 874}, + {"whenever", 875}, + {"bomb", 876}, + {"dull", 877}, + {"easily", 878}, + {"grasp", 879}, + {"hospital", 880}, + {"innocence", 881}, + {"normal", 882}, + {"receive", 883}, + {"reply", 884}, + {"rhyme", 885}, + {"shade", 886}, + {"someday", 887}, + {"sword", 888}, + {"toe", 889}, + {"visit", 890}, + {"asleep", 891}, + {"bought", 892}, + {"center", 893}, + {"consider", 894}, + {"flat", 895}, + {"hero", 896}, + {"history", 897}, + {"ink", 898}, + {"insane", 899}, + {"muscle", 900}, + {"mystery", 901}, + {"pocket", 902}, + {"reflection", 903}, + {"shove", 904}, + {"silently", 905}, + {"smart", 906}, + {"soldier", 907}, + {"spot", 908}, + {"stress", 909}, + {"train", 910}, + {"type", 911}, + {"view", 912}, + {"whether", 913}, + {"bus", 914}, + {"energy", 915}, + {"explain", 916}, + {"holy", 917}, + {"hunger", 918}, + {"inch", 919}, + {"magic", 920}, + {"mix", 921}, + {"noise", 922}, + {"nowhere", 923}, + {"prayer", 924}, + {"presence", 925}, + {"shock", 926}, + {"snap", 927}, + {"spider", 928}, + {"study", 929}, + {"thunder", 930}, + {"trail", 931}, + {"admit", 932}, + {"agree", 933}, + {"bag", 934}, + {"bang", 935}, + {"bound", 936}, + {"butterfly", 937}, + {"cute", 938}, + {"exactly", 939}, + {"explode", 940}, + {"familiar", 941}, + {"fold", 942}, + {"further", 943}, + {"pierce", 944}, + {"reflect", 945}, + {"scent", 946}, + {"selfish", 947}, + {"sharp", 948}, + {"sink", 949}, + {"spring", 950}, + {"stumble", 951}, + {"universe", 952}, + {"weep", 953}, + {"women", 954}, + {"wonderful", 955}, + {"action", 956}, + {"ancient", 957}, + {"attempt", 958}, + {"avoid", 959}, + {"birthday", 960}, + {"branch", 961}, + {"chocolate", 962}, + {"core", 963}, + {"depress", 964}, + {"drunk", 965}, + {"especially", 966}, + {"focus", 967}, + {"fruit", 968}, + {"honest", 969}, + {"match", 970}, + {"palm", 971}, + {"perfectly", 972}, + {"pillow", 973}, + {"pity", 974}, + {"poison", 975}, + {"roar", 976}, + {"shift", 977}, + {"slightly", 978}, + {"thump", 979}, + {"truck", 980}, + {"tune", 981}, + {"twenty", 982}, + {"unable", 983}, + {"wipe", 984}, + {"wrote", 985}, + {"coat", 986}, + {"constant", 987}, + {"dinner", 988}, + {"drove", 989}, + {"egg", 990}, + {"eternal", 991}, + {"flight", 992}, + {"flood", 993}, + {"frame", 994}, + {"freak", 995}, + {"gasp", 996}, + {"glad", 997}, + {"hollow", 998}, + {"motion", 999}, + {"peer", 1000}, + {"plastic", 1001}, + {"root", 1002}, + {"screen", 1003}, + {"season", 1004}, + {"sting", 1005}, + {"strike", 1006}, + {"team", 1007}, + {"unlike", 1008}, + {"victim", 1009}, + {"volume", 1010}, + {"warn", 1011}, + {"weird", 1012}, + {"attack", 1013}, + {"await", 1014}, + {"awake", 1015}, + {"built", 1016}, + {"charm", 1017}, + {"crave", 1018}, + {"despair", 1019}, + {"fought", 1020}, + {"grant", 1021}, + {"grief", 1022}, + {"horse", 1023}, + {"limit", 1024}, + {"message", 1025}, + {"ripple", 1026}, + {"sanity", 1027}, + {"scatter", 1028}, + {"serve", 1029}, + {"split", 1030}, + {"string", 1031}, + {"trick", 1032}, + {"annoy", 1033}, + {"blur", 1034}, + {"boat", 1035}, + {"brave", 1036}, + {"clearly", 1037}, + {"cling", 1038}, + {"connect", 1039}, + {"fist", 1040}, + {"forth", 1041}, + {"imagination", 1042}, + {"iron", 1043}, + {"jock", 1044}, + {"judge", 1045}, + {"lesson", 1046}, + {"milk", 1047}, + {"misery", 1048}, + {"nail", 1049}, + {"naked", 1050}, + {"ourselves", 1051}, + {"poet", 1052}, + {"possible", 1053}, + {"princess", 1054}, + {"sail", 1055}, + {"size", 1056}, + {"snake", 1057}, + {"society", 1058}, + {"stroke", 1059}, + {"torture", 1060}, + {"toss", 1061}, + {"trace", 1062}, + {"wise", 1063}, + {"bloom", 1064}, + {"bullet", 1065}, + {"cell", 1066}, + {"check", 1067}, + {"cost", 1068}, + {"darling", 1069}, + {"during", 1070}, + {"footstep", 1071}, + {"fragile", 1072}, + {"hallway", 1073}, + {"hardly", 1074}, + {"horizon", 1075}, + {"invisible", 1076}, + {"journey", 1077}, + {"midnight", 1078}, + {"mud", 1079}, + {"nod", 1080}, + {"pause", 1081}, + {"relax", 1082}, + {"shiver", 1083}, + {"sudden", 1084}, + {"value", 1085}, + {"youth", 1086}, + {"abuse", 1087}, + {"admire", 1088}, + {"blink", 1089}, + {"breast", 1090}, + {"bruise", 1091}, + {"constantly", 1092}, + {"couple", 1093}, + {"creep", 1094}, + {"curve", 1095}, + {"difference", 1096}, + {"dumb", 1097}, + {"emptiness", 1098}, + {"gotta", 1099}, + {"honor", 1100}, + {"plain", 1101}, + {"planet", 1102}, + {"recall", 1103}, + {"rub", 1104}, + {"ship", 1105}, + {"slam", 1106}, + {"soar", 1107}, + {"somebody", 1108}, + {"tightly", 1109}, + {"weather", 1110}, + {"adore", 1111}, + {"approach", 1112}, + {"bond", 1113}, + {"bread", 1114}, + {"burst", 1115}, + {"candle", 1116}, + {"coffee", 1117}, + {"cousin", 1118}, + {"crime", 1119}, + {"desert", 1120}, + {"flutter", 1121}, + {"frozen", 1122}, + {"grand", 1123}, + {"heel", 1124}, + {"hello", 1125}, + {"language", 1126}, + {"level", 1127}, + {"movement", 1128}, + {"pleasure", 1129}, + {"powerful", 1130}, + {"random", 1131}, + {"rhythm", 1132}, + {"settle", 1133}, + {"silly", 1134}, + {"slap", 1135}, + {"sort", 1136}, + {"spoken", 1137}, + {"steel", 1138}, + {"threaten", 1139}, + {"tumble", 1140}, + {"upset", 1141}, + {"aside", 1142}, + {"awkward", 1143}, + {"bee", 1144}, + {"blank", 1145}, + {"board", 1146}, + {"button", 1147}, + {"card", 1148}, + {"carefully", 1149}, + {"complain", 1150}, + {"crap", 1151}, + {"deeply", 1152}, + {"discover", 1153}, + {"drag", 1154}, + {"dread", 1155}, + {"effort", 1156}, + {"entire", 1157}, + {"fairy", 1158}, + {"giant", 1159}, + {"gotten", 1160}, + {"greet", 1161}, + {"illusion", 1162}, + {"jeans", 1163}, + {"leap", 1164}, + {"liquid", 1165}, + {"march", 1166}, + {"mend", 1167}, + {"nervous", 1168}, + {"nine", 1169}, + {"replace", 1170}, + {"rope", 1171}, + {"spine", 1172}, + {"stole", 1173}, + {"terror", 1174}, + {"accident", 1175}, + {"apple", 1176}, + {"balance", 1177}, + {"boom", 1178}, + {"childhood", 1179}, + {"collect", 1180}, + {"demand", 1181}, + {"depression", 1182}, + {"eventually", 1183}, + {"faint", 1184}, + {"glare", 1185}, + {"goal", 1186}, + {"group", 1187}, + {"honey", 1188}, + {"kitchen", 1189}, + {"laid", 1190}, + {"limb", 1191}, + {"machine", 1192}, + {"mere", 1193}, + {"mold", 1194}, + {"murder", 1195}, + {"nerve", 1196}, + {"painful", 1197}, + {"poetry", 1198}, + {"prince", 1199}, + {"rabbit", 1200}, + {"shelter", 1201}, + {"shore", 1202}, + {"shower", 1203}, + {"soothe", 1204}, + {"stair", 1205}, + {"steady", 1206}, + {"sunlight", 1207}, + {"tangle", 1208}, + {"tease", 1209}, + {"treasure", 1210}, + {"uncle", 1211}, + {"begun", 1212}, + {"bliss", 1213}, + {"canvas", 1214}, + {"cheer", 1215}, + {"claw", 1216}, + {"clutch", 1217}, + {"commit", 1218}, + {"crimson", 1219}, + {"crystal", 1220}, + {"delight", 1221}, + {"doll", 1222}, + {"existence", 1223}, + {"express", 1224}, + {"fog", 1225}, + {"football", 1226}, + {"gay", 1227}, + {"goose", 1228}, + {"guard", 1229}, + {"hatred", 1230}, + {"illuminate", 1231}, + {"mass", 1232}, + {"math", 1233}, + {"mourn", 1234}, + {"rich", 1235}, + {"rough", 1236}, + {"skip", 1237}, + {"stir", 1238}, + {"student", 1239}, + {"style", 1240}, + {"support", 1241}, + {"thorn", 1242}, + {"tough", 1243}, + {"yard", 1244}, + {"yearn", 1245}, + {"yesterday", 1246}, + {"advice", 1247}, + {"appreciate", 1248}, + {"autumn", 1249}, + {"bank", 1250}, + {"beam", 1251}, + {"bowl", 1252}, + {"capture", 1253}, + {"carve", 1254}, + {"collapse", 1255}, + {"confusion", 1256}, + {"creation", 1257}, + {"dove", 1258}, + {"feather", 1259}, + {"girlfriend", 1260}, + {"glory", 1261}, + {"government", 1262}, + {"harsh", 1263}, + {"hop", 1264}, + {"inner", 1265}, + {"loser", 1266}, + {"moonlight", 1267}, + {"neighbor", 1268}, + {"neither", 1269}, + {"peach", 1270}, + {"pig", 1271}, + {"praise", 1272}, + {"screw", 1273}, + {"shield", 1274}, + {"shimmer", 1275}, + {"sneak", 1276}, + {"stab", 1277}, + {"subject", 1278}, + {"throughout", 1279}, + {"thrown", 1280}, + {"tower", 1281}, + {"twirl", 1282}, + {"wow", 1283}, + {"army", 1284}, + {"arrive", 1285}, + {"bathroom", 1286}, + {"bump", 1287}, + {"cease", 1288}, + {"cookie", 1289}, + {"couch", 1290}, + {"courage", 1291}, + {"dim", 1292}, + {"guilt", 1293}, + {"howl", 1294}, + {"hum", 1295}, + {"husband", 1296}, + {"insult", 1297}, + {"led", 1298}, + {"lunch", 1299}, + {"mock", 1300}, + {"mostly", 1301}, + {"natural", 1302}, + {"nearly", 1303}, + {"needle", 1304}, + {"nerd", 1305}, + {"peaceful", 1306}, + {"perfection", 1307}, + {"pile", 1308}, + {"price", 1309}, + {"remove", 1310}, + {"roam", 1311}, + {"sanctuary", 1312}, + {"serious", 1313}, + {"shiny", 1314}, + {"shook", 1315}, + {"sob", 1316}, + {"stolen", 1317}, + {"tap", 1318}, + {"vain", 1319}, + {"void", 1320}, + {"warrior", 1321}, + {"wrinkle", 1322}, + {"affection", 1323}, + {"apologize", 1324}, + {"blossom", 1325}, + {"bounce", 1326}, + {"bridge", 1327}, + {"cheap", 1328}, + {"crumble", 1329}, + {"decision", 1330}, + {"descend", 1331}, + {"desperately", 1332}, + {"dig", 1333}, + {"dot", 1334}, + {"flip", 1335}, + {"frighten", 1336}, + {"heartbeat", 1337}, + {"huge", 1338}, + {"lazy", 1339}, + {"lick", 1340}, + {"odd", 1341}, + {"opinion", 1342}, + {"process", 1343}, + {"puzzle", 1344}, + {"quietly", 1345}, + {"retreat", 1346}, + {"score", 1347}, + {"sentence", 1348}, + {"separate", 1349}, + {"situation", 1350}, + {"skill", 1351}, + {"soak", 1352}, + {"square", 1353}, + {"stray", 1354}, + {"taint", 1355}, + {"task", 1356}, + {"tide", 1357}, + {"underneath", 1358}, + {"veil", 1359}, + {"whistle", 1360}, + {"anywhere", 1361}, + {"bedroom", 1362}, + {"bid", 1363}, + {"bloody", 1364}, + {"burden", 1365}, + {"careful", 1366}, + {"compare", 1367}, + {"concern", 1368}, + {"curtain", 1369}, + {"decay", 1370}, + {"defeat", 1371}, + {"describe", 1372}, + {"double", 1373}, + {"dreamer", 1374}, + {"driver", 1375}, + {"dwell", 1376}, + {"evening", 1377}, + {"flare", 1378}, + {"flicker", 1379}, + {"grandma", 1380}, + {"guitar", 1381}, + {"harm", 1382}, + {"horrible", 1383}, + {"hungry", 1384}, + {"indeed", 1385}, + {"lace", 1386}, + {"melody", 1387}, + {"monkey", 1388}, + {"nation", 1389}, + {"object", 1390}, + {"obviously", 1391}, + {"rainbow", 1392}, + {"salt", 1393}, + {"scratch", 1394}, + {"shown", 1395}, + {"shy", 1396}, + {"stage", 1397}, + {"stun", 1398}, + {"third", 1399}, + {"tickle", 1400}, + {"useless", 1401}, + {"weakness", 1402}, + {"worship", 1403}, + {"worthless", 1404}, + {"afternoon", 1405}, + {"beard", 1406}, + {"boyfriend", 1407}, + {"bubble", 1408}, + {"busy", 1409}, + {"certain", 1410}, + {"chin", 1411}, + {"concrete", 1412}, + {"desk", 1413}, + {"diamond", 1414}, + {"doom", 1415}, + {"drawn", 1416}, + {"due", 1417}, + {"felicity", 1418}, + {"freeze", 1419}, + {"frost", 1420}, + {"garden", 1421}, + {"glide", 1422}, + {"harmony", 1423}, + {"hopefully", 1424}, + {"hunt", 1425}, + {"jealous", 1426}, + {"lightning", 1427}, + {"mama", 1428}, + {"mercy", 1429}, + {"peel", 1430}, + {"physical", 1431}, + {"position", 1432}, + {"pulse", 1433}, + {"punch", 1434}, + {"quit", 1435}, + {"rant", 1436}, + {"respond", 1437}, + {"salty", 1438}, + {"sane", 1439}, + {"satisfy", 1440}, + {"savior", 1441}, + {"sheep", 1442}, + {"slept", 1443}, + {"social", 1444}, + {"sport", 1445}, + {"tuck", 1446}, + {"utter", 1447}, + {"valley", 1448}, + {"wolf", 1449}, + {"aim", 1450}, + {"alas", 1451}, + {"alter", 1452}, + {"arrow", 1453}, + {"awaken", 1454}, + {"beaten", 1455}, + {"belief", 1456}, + {"brand", 1457}, + {"ceiling", 1458}, + {"cheese", 1459}, + {"clue", 1460}, + {"confidence", 1461}, + {"connection", 1462}, + {"daily", 1463}, + {"disguise", 1464}, + {"eager", 1465}, + {"erase", 1466}, + {"essence", 1467}, + {"everytime", 1468}, + {"expression", 1469}, + {"fan", 1470}, + {"flag", 1471}, + {"flirt", 1472}, + {"foul", 1473}, + {"fur", 1474}, + {"giggle", 1475}, + {"glorious", 1476}, + {"ignorance", 1477}, + {"law", 1478}, + {"lifeless", 1479}, + {"measure", 1480}, + {"mighty", 1481}, + {"muse", 1482}, + {"north", 1483}, + {"opposite", 1484}, + {"paradise", 1485}, + {"patience", 1486}, + {"patient", 1487}, + {"pencil", 1488}, + {"petal", 1489}, + {"plate", 1490}, + {"ponder", 1491}, + {"possibly", 1492}, + {"practice", 1493}, + {"slice", 1494}, + {"spell", 1495}, + {"stock", 1496}, + {"strife", 1497}, + {"strip", 1498}, + {"suffocate", 1499}, + {"suit", 1500}, + {"tender", 1501}, + {"tool", 1502}, + {"trade", 1503}, + {"velvet", 1504}, + {"verse", 1505}, + {"waist", 1506}, + {"witch", 1507}, + {"aunt", 1508}, + {"bench", 1509}, + {"bold", 1510}, + {"cap", 1511}, + {"certainly", 1512}, + {"click", 1513}, + {"companion", 1514}, + {"creator", 1515}, + {"dart", 1516}, + {"delicate", 1517}, + {"determine", 1518}, + {"dish", 1519}, + {"dragon", 1520}, + {"drama", 1521}, + {"drum", 1522}, + {"dude", 1523}, + {"everybody", 1524}, + {"feast", 1525}, + {"forehead", 1526}, + {"former", 1527}, + {"fright", 1528}, + {"fully", 1529}, + {"gas", 1530}, + {"hook", 1531}, + {"hurl", 1532}, + {"invite", 1533}, + {"juice", 1534}, + {"manage", 1535}, + {"moral", 1536}, + {"possess", 1537}, + {"raw", 1538}, + {"rebel", 1539}, + {"royal", 1540}, + {"scale", 1541}, + {"scary", 1542}, + {"several", 1543}, + {"slight", 1544}, + {"stubborn", 1545}, + {"swell", 1546}, + {"talent", 1547}, + {"tea", 1548}, + {"terrible", 1549}, + {"thread", 1550}, + {"torment", 1551}, + {"trickle", 1552}, + {"usually", 1553}, + {"vast", 1554}, + {"violence", 1555}, + {"weave", 1556}, + {"acid", 1557}, + {"agony", 1558}, + {"ashamed", 1559}, + {"awe", 1560}, + {"belly", 1561}, + {"blend", 1562}, + {"blush", 1563}, + {"character", 1564}, + {"cheat", 1565}, + {"common", 1566}, + {"company", 1567}, + {"coward", 1568}, + {"creak", 1569}, + {"danger", 1570}, + {"deadly", 1571}, + {"defense", 1572}, + {"define", 1573}, + {"depend", 1574}, + {"desperate", 1575}, + {"destination", 1576}, + {"dew", 1577}, + {"duck", 1578}, + {"dusty", 1579}, + {"embarrass", 1580}, + {"engine", 1581}, + {"example", 1582}, + {"explore", 1583}, + {"foe", 1584}, + {"freely", 1585}, + {"frustrate", 1586}, + {"generation", 1587}, + {"glove", 1588}, + {"guilty", 1589}, + {"health", 1590}, + {"hurry", 1591}, + {"idiot", 1592}, + {"impossible", 1593}, + {"inhale", 1594}, + {"jaw", 1595}, + {"kingdom", 1596}, + {"mention", 1597}, + {"mist", 1598}, + {"moan", 1599}, + {"mumble", 1600}, + {"mutter", 1601}, + {"observe", 1602}, + {"ode", 1603}, + {"pathetic", 1604}, + {"pattern", 1605}, + {"pie", 1606}, + {"prefer", 1607}, + {"puff", 1608}, + {"rape", 1609}, + {"rare", 1610}, + {"revenge", 1611}, + {"rude", 1612}, + {"scrape", 1613}, + {"spiral", 1614}, + {"squeeze", 1615}, + {"strain", 1616}, + {"sunset", 1617}, + {"suspend", 1618}, + {"sympathy", 1619}, + {"thigh", 1620}, + {"throne", 1621}, + {"total", 1622}, + {"unseen", 1623}, + {"weapon", 1624}, + {"weary", 1625} + }; + + const std::string wordsArray[] = { + "like", + "just", + "love", + "know", + "never", + "want", + "time", + "out", + "there", + "make", + "look", + "eye", + "down", + "only", + "think", + "heart", + "back", + "then", + "into", + "about", + "more", + "away", + "still", + "them", + "take", + "thing", + "even", + "through", + "long", + "always", + "world", + "too", + "friend", + "tell", + "try", + "hand", + "thought", + "over", + "here", + "other", + "need", + "smile", + "again", + "much", + "cry", + "been", + "night", + "ever", + "little", + "said", + "end", + "some", + "those", + "around", + "mind", + "people", + "girl", + "leave", + "dream", + "left", + "turn", + "myself", + "give", + "nothing", + "really", + "off", + "before", + "something", + "find", + "walk", + "wish", + "good", + "once", + "place", + "ask", + "stop", + "keep", + "watch", + "seem", + "everything", + "wait", + "got", + "yet", + "made", + "remember", + "start", + "alone", + "run", + "hope", + "maybe", + "believe", + "body", + "hate", + "after", + "close", + "talk", + "stand", + "own", + "each", + "hurt", + "help", + "home", + "god", + "soul", + "new", + "many", + "two", + "inside", + "should", + "true", + "first", + "fear", + "mean", + "better", + "play", + "another", + "gone", + "change", + "use", + "wonder", + "someone", + "hair", + "cold", + "open", + "best", + "any", + "behind", + "happen", + "water", + "dark", + "laugh", + "stay", + "forever", + "name", + "work", + "show", + "sky", + "break", + "came", + "deep", + "door", + "put", + "black", + "together", + "upon", + "happy", + "such", + "great", + "white", + "matter", + "fill", + "past", + "please", + "burn", + "cause", + "enough", + "touch", + "moment", + "soon", + "voice", + "scream", + "anything", + "stare", + "sound", + "red", + "everyone", + "hide", + "kiss", + "truth", + "death", + "beautiful", + "mine", + "blood", + "broken", + "very", + "pass", + "next", + "forget", + "tree", + "wrong", + "air", + "mother", + "understand", + "lip", + "hit", + "wall", + "memory", + "sleep", + "free", + "high", + "realize", + "school", + "might", + "skin", + "sweet", + "perfect", + "blue", + "kill", + "breath", + "dance", + "against", + "fly", + "between", + "grow", + "strong", + "under", + "listen", + "bring", + "sometimes", + "speak", + "pull", + "person", + "become", + "family", + "begin", + "ground", + "real", + "small", + "father", + "sure", + "feet", + "rest", + "young", + "finally", + "land", + "across", + "today", + "different", + "guy", + "line", + "fire", + "reason", + "reach", + "second", + "slowly", + "write", + "eat", + "smell", + "mouth", + "step", + "learn", + "three", + "floor", + "promise", + "breathe", + "darkness", + "push", + "earth", + "guess", + "save", + "song", + "above", + "along", + "both", + "color", + "house", + "almost", + "sorry", + "anymore", + "brother", + "okay", + "dear", + "game", + "fade", + "already", + "apart", + "warm", + "beauty", + "heard", + "notice", + "question", + "shine", + "began", + "piece", + "whole", + "shadow", + "secret", + "street", + "within", + "finger", + "point", + "morning", + "whisper", + "child", + "moon", + "green", + "story", + "glass", + "kid", + "silence", + "since", + "soft", + "yourself", + "empty", + "shall", + "angel", + "answer", + "baby", + "bright", + "dad", + "path", + "worry", + "hour", + "drop", + "follow", + "power", + "war", + "half", + "flow", + "heaven", + "act", + "chance", + "fact", + "least", + "tired", + "children", + "near", + "quite", + "afraid", + "rise", + "sea", + "taste", + "window", + "cover", + "nice", + "trust", + "lot", + "sad", + "cool", + "force", + "peace", + "return", + "blind", + "easy", + "ready", + "roll", + "rose", + "drive", + "held", + "music", + "beneath", + "hang", + "mom", + "paint", + "emotion", + "quiet", + "clear", + "cloud", + "few", + "pretty", + "bird", + "outside", + "paper", + "picture", + "front", + "rock", + "simple", + "anyone", + "meant", + "reality", + "road", + "sense", + "waste", + "bit", + "leaf", + "thank", + "happiness", + "meet", + "men", + "smoke", + "truly", + "decide", + "self", + "age", + "book", + "form", + "alive", + "carry", + "escape", + "damn", + "instead", + "able", + "ice", + "minute", + "throw", + "catch", + "leg", + "ring", + "course", + "goodbye", + "lead", + "poem", + "sick", + "corner", + "desire", + "known", + "problem", + "remind", + "shoulder", + "suppose", + "toward", + "wave", + "drink", + "jump", + "woman", + "pretend", + "sister", + "week", + "human", + "joy", + "crack", + "grey", + "pray", + "surprise", + "dry", + "knee", + "less", + "search", + "bleed", + "caught", + "clean", + "embrace", + "future", + "king", + "son", + "sorrow", + "chest", + "hug", + "remain", + "sat", + "worth", + "blow", + "daddy", + "final", + "parent", + "tight", + "also", + "create", + "lonely", + "safe", + "cross", + "dress", + "evil", + "silent", + "bone", + "fate", + "perhaps", + "anger", + "class", + "scar", + "snow", + "tiny", + "tonight", + "continue", + "control", + "dog", + "edge", + "mirror", + "month", + "suddenly", + "comfort", + "given", + "loud", + "quickly", + "gaze", + "plan", + "rush", + "stone", + "town", + "battle", + "ignore", + "spirit", + "stood", + "stupid", + "yours", + "brown", + "build", + "dust", + "hey", + "kept", + "pay", + "phone", + "twist", + "although", + "ball", + "beyond", + "hidden", + "nose", + "taken", + "fail", + "float", + "pure", + "somehow", + "wash", + "wrap", + "angry", + "cheek", + "creature", + "forgotten", + "heat", + "rip", + "single", + "space", + "special", + "weak", + "whatever", + "yell", + "anyway", + "blame", + "job", + "choose", + "country", + "curse", + "drift", + "echo", + "figure", + "grew", + "laughter", + "neck", + "suffer", + "worse", + "yeah", + "disappear", + "foot", + "forward", + "knife", + "mess", + "somewhere", + "stomach", + "storm", + "beg", + "idea", + "lift", + "offer", + "breeze", + "field", + "five", + "often", + "simply", + "stuck", + "win", + "allow", + "confuse", + "enjoy", + "except", + "flower", + "seek", + "strength", + "calm", + "grin", + "gun", + "heavy", + "hill", + "large", + "ocean", + "shoe", + "sigh", + "straight", + "summer", + "tongue", + "accept", + "crazy", + "everyday", + "exist", + "grass", + "mistake", + "sent", + "shut", + "surround", + "table", + "ache", + "brain", + "destroy", + "heal", + "nature", + "shout", + "sign", + "stain", + "choice", + "doubt", + "glance", + "glow", + "mountain", + "queen", + "stranger", + "throat", + "tomorrow", + "city", + "either", + "fish", + "flame", + "rather", + "shape", + "spin", + "spread", + "ash", + "distance", + "finish", + "image", + "imagine", + "important", + "nobody", + "shatter", + "warmth", + "became", + "feed", + "flesh", + "funny", + "lust", + "shirt", + "trouble", + "yellow", + "attention", + "bare", + "bite", + "money", + "protect", + "amaze", + "appear", + "born", + "choke", + "completely", + "daughter", + "fresh", + "friendship", + "gentle", + "probably", + "six", + "deserve", + "expect", + "grab", + "middle", + "nightmare", + "river", + "thousand", + "weight", + "worst", + "wound", + "barely", + "bottle", + "cream", + "regret", + "relationship", + "stick", + "test", + "crush", + "endless", + "fault", + "itself", + "rule", + "spill", + "art", + "circle", + "join", + "kick", + "mask", + "master", + "passion", + "quick", + "raise", + "smooth", + "unless", + "wander", + "actually", + "broke", + "chair", + "deal", + "favorite", + "gift", + "note", + "number", + "sweat", + "box", + "chill", + "clothes", + "lady", + "mark", + "park", + "poor", + "sadness", + "tie", + "animal", + "belong", + "brush", + "consume", + "dawn", + "forest", + "innocent", + "pen", + "pride", + "stream", + "thick", + "clay", + "complete", + "count", + "draw", + "faith", + "press", + "silver", + "struggle", + "surface", + "taught", + "teach", + "wet", + "bless", + "chase", + "climb", + "enter", + "letter", + "melt", + "metal", + "movie", + "stretch", + "swing", + "vision", + "wife", + "beside", + "crash", + "forgot", + "guide", + "haunt", + "joke", + "knock", + "plant", + "pour", + "prove", + "reveal", + "steal", + "stuff", + "trip", + "wood", + "wrist", + "bother", + "bottom", + "crawl", + "crowd", + "fix", + "forgive", + "frown", + "grace", + "loose", + "lucky", + "party", + "release", + "surely", + "survive", + "teacher", + "gently", + "grip", + "speed", + "suicide", + "travel", + "treat", + "vein", + "written", + "cage", + "chain", + "conversation", + "date", + "enemy", + "however", + "interest", + "million", + "page", + "pink", + "proud", + "sway", + "themselves", + "winter", + "church", + "cruel", + "cup", + "demon", + "experience", + "freedom", + "pair", + "pop", + "purpose", + "respect", + "shoot", + "softly", + "state", + "strange", + "bar", + "birth", + "curl", + "dirt", + "excuse", + "lord", + "lovely", + "monster", + "order", + "pack", + "pants", + "pool", + "scene", + "seven", + "shame", + "slide", + "ugly", + "among", + "blade", + "blonde", + "closet", + "creek", + "deny", + "drug", + "eternity", + "gain", + "grade", + "handle", + "key", + "linger", + "pale", + "prepare", + "swallow", + "swim", + "tremble", + "wheel", + "won", + "cast", + "cigarette", + "claim", + "college", + "direction", + "dirty", + "gather", + "ghost", + "hundred", + "loss", + "lung", + "orange", + "present", + "swear", + "swirl", + "twice", + "wild", + "bitter", + "blanket", + "doctor", + "everywhere", + "flash", + "grown", + "knowledge", + "numb", + "pressure", + "radio", + "repeat", + "ruin", + "spend", + "unknown", + "buy", + "clock", + "devil", + "early", + "false", + "fantasy", + "pound", + "precious", + "refuse", + "sheet", + "teeth", + "welcome", + "add", + "ahead", + "block", + "bury", + "caress", + "content", + "depth", + "despite", + "distant", + "marry", + "purple", + "threw", + "whenever", + "bomb", + "dull", + "easily", + "grasp", + "hospital", + "innocence", + "normal", + "receive", + "reply", + "rhyme", + "shade", + "someday", + "sword", + "toe", + "visit", + "asleep", + "bought", + "center", + "consider", + "flat", + "hero", + "history", + "ink", + "insane", + "muscle", + "mystery", + "pocket", + "reflection", + "shove", + "silently", + "smart", + "soldier", + "spot", + "stress", + "train", + "type", + "view", + "whether", + "bus", + "energy", + "explain", + "holy", + "hunger", + "inch", + "magic", + "mix", + "noise", + "nowhere", + "prayer", + "presence", + "shock", + "snap", + "spider", + "study", + "thunder", + "trail", + "admit", + "agree", + "bag", + "bang", + "bound", + "butterfly", + "cute", + "exactly", + "explode", + "familiar", + "fold", + "further", + "pierce", + "reflect", + "scent", + "selfish", + "sharp", + "sink", + "spring", + "stumble", + "universe", + "weep", + "women", + "wonderful", + "action", + "ancient", + "attempt", + "avoid", + "birthday", + "branch", + "chocolate", + "core", + "depress", + "drunk", + "especially", + "focus", + "fruit", + "honest", + "match", + "palm", + "perfectly", + "pillow", + "pity", + "poison", + "roar", + "shift", + "slightly", + "thump", + "truck", + "tune", + "twenty", + "unable", + "wipe", + "wrote", + "coat", + "constant", + "dinner", + "drove", + "egg", + "eternal", + "flight", + "flood", + "frame", + "freak", + "gasp", + "glad", + "hollow", + "motion", + "peer", + "plastic", + "root", + "screen", + "season", + "sting", + "strike", + "team", + "unlike", + "victim", + "volume", + "warn", + "weird", + "attack", + "await", + "awake", + "built", + "charm", + "crave", + "despair", + "fought", + "grant", + "grief", + "horse", + "limit", + "message", + "ripple", + "sanity", + "scatter", + "serve", + "split", + "string", + "trick", + "annoy", + "blur", + "boat", + "brave", + "clearly", + "cling", + "connect", + "fist", + "forth", + "imagination", + "iron", + "jock", + "judge", + "lesson", + "milk", + "misery", + "nail", + "naked", + "ourselves", + "poet", + "possible", + "princess", + "sail", + "size", + "snake", + "society", + "stroke", + "torture", + "toss", + "trace", + "wise", + "bloom", + "bullet", + "cell", + "check", + "cost", + "darling", + "during", + "footstep", + "fragile", + "hallway", + "hardly", + "horizon", + "invisible", + "journey", + "midnight", + "mud", + "nod", + "pause", + "relax", + "shiver", + "sudden", + "value", + "youth", + "abuse", + "admire", + "blink", + "breast", + "bruise", + "constantly", + "couple", + "creep", + "curve", + "difference", + "dumb", + "emptiness", + "gotta", + "honor", + "plain", + "planet", + "recall", + "rub", + "ship", + "slam", + "soar", + "somebody", + "tightly", + "weather", + "adore", + "approach", + "bond", + "bread", + "burst", + "candle", + "coffee", + "cousin", + "crime", + "desert", + "flutter", + "frozen", + "grand", + "heel", + "hello", + "language", + "level", + "movement", + "pleasure", + "powerful", + "random", + "rhythm", + "settle", + "silly", + "slap", + "sort", + "spoken", + "steel", + "threaten", + "tumble", + "upset", + "aside", + "awkward", + "bee", + "blank", + "board", + "button", + "card", + "carefully", + "complain", + "crap", + "deeply", + "discover", + "drag", + "dread", + "effort", + "entire", + "fairy", + "giant", + "gotten", + "greet", + "illusion", + "jeans", + "leap", + "liquid", + "march", + "mend", + "nervous", + "nine", + "replace", + "rope", + "spine", + "stole", + "terror", + "accident", + "apple", + "balance", + "boom", + "childhood", + "collect", + "demand", + "depression", + "eventually", + "faint", + "glare", + "goal", + "group", + "honey", + "kitchen", + "laid", + "limb", + "machine", + "mere", + "mold", + "murder", + "nerve", + "painful", + "poetry", + "prince", + "rabbit", + "shelter", + "shore", + "shower", + "soothe", + "stair", + "steady", + "sunlight", + "tangle", + "tease", + "treasure", + "uncle", + "begun", + "bliss", + "canvas", + "cheer", + "claw", + "clutch", + "commit", + "crimson", + "crystal", + "delight", + "doll", + "existence", + "express", + "fog", + "football", + "gay", + "goose", + "guard", + "hatred", + "illuminate", + "mass", + "math", + "mourn", + "rich", + "rough", + "skip", + "stir", + "student", + "style", + "support", + "thorn", + "tough", + "yard", + "yearn", + "yesterday", + "advice", + "appreciate", + "autumn", + "bank", + "beam", + "bowl", + "capture", + "carve", + "collapse", + "confusion", + "creation", + "dove", + "feather", + "girlfriend", + "glory", + "government", + "harsh", + "hop", + "inner", + "loser", + "moonlight", + "neighbor", + "neither", + "peach", + "pig", + "praise", + "screw", + "shield", + "shimmer", + "sneak", + "stab", + "subject", + "throughout", + "thrown", + "tower", + "twirl", + "wow", + "army", + "arrive", + "bathroom", + "bump", + "cease", + "cookie", + "couch", + "courage", + "dim", + "guilt", + "howl", + "hum", + "husband", + "insult", + "led", + "lunch", + "mock", + "mostly", + "natural", + "nearly", + "needle", + "nerd", + "peaceful", + "perfection", + "pile", + "price", + "remove", + "roam", + "sanctuary", + "serious", + "shiny", + "shook", + "sob", + "stolen", + "tap", + "vain", + "void", + "warrior", + "wrinkle", + "affection", + "apologize", + "blossom", + "bounce", + "bridge", + "cheap", + "crumble", + "decision", + "descend", + "desperately", + "dig", + "dot", + "flip", + "frighten", + "heartbeat", + "huge", + "lazy", + "lick", + "odd", + "opinion", + "process", + "puzzle", + "quietly", + "retreat", + "score", + "sentence", + "separate", + "situation", + "skill", + "soak", + "square", + "stray", + "taint", + "task", + "tide", + "underneath", + "veil", + "whistle", + "anywhere", + "bedroom", + "bid", + "bloody", + "burden", + "careful", + "compare", + "concern", + "curtain", + "decay", + "defeat", + "describe", + "double", + "dreamer", + "driver", + "dwell", + "evening", + "flare", + "flicker", + "grandma", + "guitar", + "harm", + "horrible", + "hungry", + "indeed", + "lace", + "melody", + "monkey", + "nation", + "object", + "obviously", + "rainbow", + "salt", + "scratch", + "shown", + "shy", + "stage", + "stun", + "third", + "tickle", + "useless", + "weakness", + "worship", + "worthless", + "afternoon", + "beard", + "boyfriend", + "bubble", + "busy", + "certain", + "chin", + "concrete", + "desk", + "diamond", + "doom", + "drawn", + "due", + "felicity", + "freeze", + "frost", + "garden", + "glide", + "harmony", + "hopefully", + "hunt", + "jealous", + "lightning", + "mama", + "mercy", + "peel", + "physical", + "position", + "pulse", + "punch", + "quit", + "rant", + "respond", + "salty", + "sane", + "satisfy", + "savior", + "sheep", + "slept", + "social", + "sport", + "tuck", + "utter", + "valley", + "wolf", + "aim", + "alas", + "alter", + "arrow", + "awaken", + "beaten", + "belief", + "brand", + "ceiling", + "cheese", + "clue", + "confidence", + "connection", + "daily", + "disguise", + "eager", + "erase", + "essence", + "everytime", + "expression", + "fan", + "flag", + "flirt", + "foul", + "fur", + "giggle", + "glorious", + "ignorance", + "law", + "lifeless", + "measure", + "mighty", + "muse", + "north", + "opposite", + "paradise", + "patience", + "patient", + "pencil", + "petal", + "plate", + "ponder", + "possibly", + "practice", + "slice", + "spell", + "stock", + "strife", + "strip", + "suffocate", + "suit", + "tender", + "tool", + "trade", + "velvet", + "verse", + "waist", + "witch", + "aunt", + "bench", + "bold", + "cap", + "certainly", + "click", + "companion", + "creator", + "dart", + "delicate", + "determine", + "dish", + "dragon", + "drama", + "drum", + "dude", + "everybody", + "feast", + "forehead", + "former", + "fright", + "fully", + "gas", + "hook", + "hurl", + "invite", + "juice", + "manage", + "moral", + "possess", + "raw", + "rebel", + "royal", + "scale", + "scary", + "several", + "slight", + "stubborn", + "swell", + "talent", + "tea", + "terrible", + "thread", + "torment", + "trickle", + "usually", + "vast", + "violence", + "weave", + "acid", + "agony", + "ashamed", + "awe", + "belly", + "blend", + "blush", + "character", + "cheat", + "common", + "company", + "coward", + "creak", + "danger", + "deadly", + "defense", + "define", + "depend", + "desperate", + "destination", + "dew", + "duck", + "dusty", + "embarrass", + "engine", + "example", + "explore", + "foe", + "freely", + "frustrate", + "generation", + "glove", + "guilty", + "health", + "hurry", + "idiot", + "impossible", + "inhale", + "jaw", + "kingdom", + "mention", + "mist", + "moan", + "mumble", + "mutter", + "observe", + "ode", + "pathetic", + "pattern", + "pie", + "prefer", + "puff", + "rape", + "rare", + "revenge", + "rude", + "scrape", + "spiral", + "squeeze", + "strain", + "sunset", + "suspend", + "sympathy", + "thigh", + "throne", + "total", + "unseen", + "weapon", + "weary" + }; + } +} diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h index a992a9db0..295f59e51 100644 --- a/src/cryptonote_config.h +++ b/src/cryptonote_config.h @@ -51,6 +51,8 @@ #define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT 200 //by default, blocks count in blocks downloading #define CRYPTONOTE_PROTOCOL_HOP_RELAX_COUNT 3 //value of hop, after which we use only announce of new block +#define CRYPTONOTE_MEMPOOL_TX_LIVETIME 86400 //seconds, one day +#define CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME 604800 //seconds, one week #define P2P_DEFAULT_PORT 18080 #define RPC_DEFAULT_PORT 18081 diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp index ba39b9b77..3bedd7404 100644 --- a/src/cryptonote_core/account.cpp +++ b/src/cryptonote_core/account.cpp @@ -10,6 +10,10 @@ #include "account.h" #include "warnings.h" #include "crypto/crypto.h" +extern "C" +{ +#include "crypto/keccak.h" +} #include "cryptonote_core/cryptonote_basic_impl.h" #include "cryptonote_core/cryptonote_format_utils.h" using namespace std; @@ -29,11 +33,17 @@ DISABLE_VS_WARNINGS(4244 4345) m_keys = account_keys(); } //----------------------------------------------------------------- - void account_base::generate() + crypto::secret_key account_base::generate(const crypto::secret_key& recovery_key, bool recover, bool two_random) { - generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key); - generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key); + crypto::secret_key first = generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, recovery_key, recover); + + // rng for generating second set of keys is hash of first rng. means only one set of electrum-style words needed for recovery + crypto::secret_key second; + keccak((uint8_t *)&first, sizeof(crypto::secret_key), (uint8_t *)&second, sizeof(crypto::secret_key)); + + generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key, second, two_random ? false : true); m_creation_timestamp = time(NULL); + return first; } //----------------------------------------------------------------- const account_keys& account_base::get_keys() const diff --git a/src/cryptonote_core/account.h b/src/cryptonote_core/account.h index 8b525da97..cb77d7c4e 100644 --- a/src/cryptonote_core/account.h +++ b/src/cryptonote_core/account.h @@ -31,7 +31,7 @@ namespace cryptonote { public: account_base(); - void generate(); + crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false); const account_keys& get_keys() const; std::string get_public_address_str(); diff --git a/src/cryptonote_core/checkpoints_create.h b/src/cryptonote_core/checkpoints_create.h index 3ecbbf0b6..a92fefd3f 100644 --- a/src/cryptonote_core/checkpoints_create.h +++ b/src/cryptonote_core/checkpoints_create.h @@ -15,6 +15,7 @@ namespace cryptonote { ADD_CHECKPOINT(22231, "7cb10e29d67e1c069e6e11b17d30b809724255fee2f6868dc14cfc6ed44dfb25"); ADD_CHECKPOINT(29556, "53c484a8ed91e4da621bb2fa88106dbde426fe90d7ef07b9c1e5127fb6f3a7f6"); ADD_CHECKPOINT(50000, "0fe8758ab06a8b9cb35b7328fd4f757af530a5d37759f9d3e421023231f7b31c"); + ADD_CHECKPOINT(80000, "a62dcd7b536f22e003ebae8726e9e7276f63d594e264b6f0cd7aab27b66e75e3"); return true; } } diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index b2389fce2..2609fc13e 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -432,6 +432,18 @@ namespace cryptonote return true; } //----------------------------------------------------------------------------------------------- + // Used by the RPC server to check the size of an incoming + // block_blob + bool core::check_incoming_block_size(const blobdata& block_blob) + { + if(block_blob.size() > get_max_block_size()) + { + LOG_PRINT_L0("WRONG BLOCK BLOB, too big size " << block_blob.size() << ", rejected"); + return false; + } + return true; + } + //----------------------------------------------------------------------------------------------- crypto::hash core::get_tail_id() { return m_blockchain_storage.get_tail_id(); @@ -514,6 +526,7 @@ namespace cryptonote m_store_blockchain_interval.do_call(boost::bind(&blockchain_storage::store_blockchain, &m_blockchain_storage)); m_miner.on_idle(); + m_mempool.on_idle(); return true; } //----------------------------------------------------------------------------------------------- diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 7ef0f8b1d..1f1b6eec6 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -34,6 +34,7 @@ namespace cryptonote bool on_idle(); bool handle_incoming_tx(const blobdata& tx_blob, tx_verification_context& tvc, bool keeped_by_block); bool handle_incoming_block(const blobdata& block_blob, block_verification_context& bvc, bool update_miner_blocktemplate = true); + bool check_incoming_block_size(const blobdata& block_blob); i_cryptonote_protocol* get_protocol(){return m_pprotocol;} //-------------------- i_miner_handler ----------------------- diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index 4c4c6aea1..ce1bc1ad2 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -83,6 +83,7 @@ namespace cryptonote txd_p.first->second.max_used_block_id = null_hash; txd_p.first->second.max_used_block_height = 0; txd_p.first->second.kept_by_block = kept_by_block; + txd_p.first->second.receive_time = time(nullptr); tvc.m_verifivation_impossible = true; tvc.m_added_to_pool = true; }else @@ -104,6 +105,7 @@ namespace cryptonote txd_p.first->second.max_used_block_height = max_used_block_height; txd_p.first->second.last_failed_height = 0; txd_p.first->second.last_failed_id = null_hash; + txd_p.first->second.receive_time = time(nullptr); tvc.m_added_to_pool = true; if(txd_p.first->second.fee > 0) @@ -178,6 +180,30 @@ namespace cryptonote return true; } //--------------------------------------------------------------------------------- + void tx_memory_pool::on_idle() + { + m_remove_stuck_tx_interval.do_call([this](){return remove_stuck_transactions();}); + } + //--------------------------------------------------------------------------------- + //proper tx_pool handling courtesy of CryptoZoidberg and Boolberry + bool tx_memory_pool::remove_stuck_transactions() + { + CRITICAL_REGION_LOCAL(m_transactions_lock); + for(auto it = m_transactions.begin(); it!= m_transactions.end();) + { + uint64_t tx_age = time(nullptr) - it->second.receive_time; + + if((tx_age > CRYPTONOTE_MEMPOOL_TX_LIVETIME && !it->second.kept_by_block) || + (tx_age > CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME && it->second.kept_by_block) ) + { + LOG_PRINT_L0("Tx " << it->first << " removed from tx pool due to outdated, age: " << tx_age ); + m_transactions.erase(it++); + }else + ++it; + } + return true; + } + //--------------------------------------------------------------------------------- size_t tx_memory_pool::get_transactions_count() { CRITICAL_REGION_LOCAL(m_transactions_lock); diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 26d273aa7..649af41a3 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -13,6 +13,7 @@ #include "string_tools.h" #include "syncobj.h" +#include "math_helper.h" #include "cryptonote_basic_impl.h" #include "verification_context.h" #include "crypto/hash.h" @@ -40,6 +41,7 @@ namespace cryptonote bool on_blockchain_inc(uint64_t new_block_height, const crypto::hash& top_block_id); bool on_blockchain_dec(uint64_t new_block_height, const crypto::hash& top_block_id); + void on_idle(); void lock(); void unlock(); @@ -59,7 +61,7 @@ namespace cryptonote /*bool flush_pool(const std::strig& folder); bool inflate_pool(const std::strig& folder);*/ -#define CURRENT_MEMPOOL_ARCHIVE_VER 7 +#define CURRENT_MEMPOOL_ARCHIVE_VER 8 template<class archive_t> void serialize(archive_t & a, const unsigned int version) @@ -82,9 +84,11 @@ namespace cryptonote // uint64_t last_failed_height; crypto::hash last_failed_id; + time_t receive_time; }; private: + bool remove_stuck_transactions(); bool is_transaction_ready_to_go(tx_details& txd); typedef std::unordered_map<crypto::hash, tx_details > transactions_container; typedef std::unordered_map<crypto::key_image, std::unordered_set<crypto::hash> > key_images_container; @@ -92,6 +96,7 @@ namespace cryptonote epee::critical_section m_transactions_lock; transactions_container m_transactions; key_images_container m_spent_key_images; + epee::math_helper::once_a_time_seconds<30> m_remove_stuck_tx_interval; //transactions_container m_alternative_transactions; @@ -159,6 +164,7 @@ namespace boost ar & td.max_used_block_id; ar & td.last_failed_height; ar & td.last_failed_id; + ar & td.receive_time; } } diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 04ed2c687..c3f98563d 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -449,6 +449,15 @@ namespace cryptonote return false; } + // Fix from Boolberry neglects to check block + // size, do that with the function below + if(!m_core.check_incoming_block_size(blockblob)) + { + error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB_SIZE; + error_resp.message = "Block bloc size is too big, rejecting block"; + return false; + } + if(!m_core.handle_block_found(b)) { error_resp.code = CORE_RPC_ERROR_CODE_BLOCK_NOT_ACCEPTED; diff --git a/src/rpc/core_rpc_server_error_codes.h b/src/rpc/core_rpc_server_error_codes.h index 10785f8ab..273a8b8cb 100644 --- a/src/rpc/core_rpc_server_error_codes.h +++ b/src/rpc/core_rpc_server_error_codes.h @@ -13,7 +13,6 @@ #define CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB -6 #define CORE_RPC_ERROR_CODE_BLOCK_NOT_ACCEPTED -7 #define CORE_RPC_ERROR_CODE_CORE_BUSY -9 - - +#define CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB_SIZE -10 diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 4cab12c22..6af0de9f9 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <thread> +#include <iostream> #include <boost/lexical_cast.hpp> #include <boost/program_options.hpp> #include <boost/algorithm/string.hpp> @@ -17,6 +18,8 @@ #include "rpc/core_rpc_server_commands_defs.h" #include "wallet/wallet_rpc_server.h" #include "version.h" +#include "crypto/crypto.h" // for crypto::secret_key definition +#include "crypto/electrum-words.h" #if defined(WIN32) #include <crtdbg.h> @@ -38,6 +41,9 @@ namespace const command_line::arg_descriptor<std::string> arg_daemon_address = {"daemon-address", "Use daemon instance at <host>:<port>", ""}; const command_line::arg_descriptor<std::string> arg_daemon_host = {"daemon-host", "Use daemon instance at host <arg> instead of localhost", ""}; const command_line::arg_descriptor<std::string> arg_password = {"password", "Wallet password", "", true}; + const command_line::arg_descriptor<std::string> arg_electrum_seed = {"electrum-seed", "Specify electrum seed for wallet recovery/creation", ""}; + const command_line::arg_descriptor<bool> arg_restore_deterministic_wallet = {"restore-deterministic-wallet", "Recover wallet using electrum-style mnemonic", false}; + const command_line::arg_descriptor<bool> arg_non_deterministic = {"non-deterministic", "creates non-deterministic view and spend keys", false}; const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", "Use daemon instance at port <arg> instead of 8081", 0}; const command_line::arg_descriptor<uint32_t> arg_log_level = {"set_log", "", 0, true}; @@ -208,17 +214,25 @@ bool simple_wallet::ask_wallet_create_if_needed() { std::string wallet_path; - std::cout << "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n"; - std::cout << "Wallet file name: "; - - std::getline(std::cin, wallet_path); - - wallet_path = string_tools::trim(wallet_path); + wallet_path = command_line::input_line( + "Specify wallet file name (e.g., wallet.bin). If the wallet doesn't exist, it will be created.\n" + "Wallet file name: " + ); bool keys_file_exists; bool wallet_file_exists; tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists); + // add logic to error out if new wallet requested but named wallet file exists + if (keys_file_exists || wallet_file_exists) + { + if (!m_generate_new.empty() || m_restore_deterministic_wallet) + { + fail_msg_writer() << "Attempting to generate or restore wallet, but specified file(s) exist. Exiting to not risk overwriting."; + return false; + } + } + bool r; if(keys_file_exists) { @@ -251,13 +265,14 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) return false; } - size_t c = 0; - if(!m_generate_new.empty()) ++c; - if(!m_wallet_file.empty()) ++c; - if (1 != c) + if(!m_generate_new.empty() && !m_wallet_file.empty()) { - if(!ask_wallet_create_if_needed()) - return false; + fail_msg_writer() << "Specifying both --generate-new-wallet=\"wallet_name\" and --wallet-file=\"wallet_name\" doesn't make sense!"; + return false; + } + else if (m_generate_new.empty() && m_wallet_file.empty()) + { + if(!ask_wallet_create_if_needed()) return false; } if (m_daemon_host.empty()) @@ -282,9 +297,36 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) } } - if (!m_generate_new.empty()) + if (!m_generate_new.empty() || m_restore_deterministic_wallet) { - bool r = new_wallet(m_generate_new, pwd_container.password()); + if (m_wallet_file.empty()) m_wallet_file = m_generate_new; // alias for simplicity later + + // check for recover flag. if present, require electrum word list (only recovery option for now). + if (m_restore_deterministic_wallet) + { + if (m_non_deterministic) + { + fail_msg_writer() << "Cannot specify both --restore-deterministic-wallet and --non-deterministic"; + return false; + } + + if (m_electrum_seed.empty()) + { + m_electrum_seed = command_line::input_line("Specify electrum seed: "); + if (m_electrum_seed.empty()) + { + fail_msg_writer() << "specify a recovery parameter with the --electrum-seed=\"words list here\""; + return false; + } + } + + if (!crypto::ElectrumWords::words_to_bytes(m_electrum_seed, m_recovery_key)) + { + fail_msg_writer() << "electrum-style word list failed verification"; + return false; + } + } + bool r = new_wallet(m_wallet_file, pwd_container.password(), m_recovery_key, m_restore_deterministic_wallet, m_non_deterministic); CHECK_AND_ASSERT_MES(r, false, "account creation failed"); } else @@ -306,11 +348,14 @@ bool simple_wallet::deinit() //---------------------------------------------------------------------------------------------------- void simple_wallet::handle_command_line(const boost::program_options::variables_map& vm) { - m_wallet_file = command_line::get_arg(vm, arg_wallet_file); - m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet); - m_daemon_address = command_line::get_arg(vm, arg_daemon_address); - m_daemon_host = command_line::get_arg(vm, arg_daemon_host); - m_daemon_port = command_line::get_arg(vm, arg_daemon_port); + m_wallet_file = command_line::get_arg(vm, arg_wallet_file); + m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet); + m_daemon_address = command_line::get_arg(vm, arg_daemon_address); + m_daemon_host = command_line::get_arg(vm, arg_daemon_host); + m_daemon_port = command_line::get_arg(vm, arg_daemon_port); + m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed); + m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet); + m_non_deterministic = command_line::get_arg(vm, arg_non_deterministic); } //---------------------------------------------------------------------------------------------------- bool simple_wallet::try_connect_to_daemon() @@ -324,16 +369,19 @@ bool simple_wallet::try_connect_to_daemon() } return true; } + //---------------------------------------------------------------------------------------------------- -bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password) +bool simple_wallet::new_wallet(const string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key, bool recover, bool two_random) { m_wallet_file = wallet_file; m_wallet.reset(new tools::wallet2()); m_wallet->callback(this); + + crypto::secret_key recovery_val; try { - m_wallet->generate(wallet_file, password); + recovery_val = m_wallet->generate(wallet_file, password, recovery_key, recover, two_random); message_writer(epee::log_space::console_color_white, true) << "Generated new wallet: " << m_wallet->get_account().get_public_address_str() << std::endl << "view key: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key); } catch (const std::exception& e) @@ -344,6 +392,13 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas m_wallet->init(m_daemon_address); + // convert rng value to electrum-style word list + std::string electrum_words; + crypto::ElectrumWords::bytes_to_words(recovery_val, electrum_words); + + std::string print_electrum = ""; + + success_msg_writer() << "**********************************************************************\n" << "Your wallet has been generated.\n" << @@ -351,8 +406,16 @@ bool simple_wallet::new_wallet(const string &wallet_file, const std::string& pas "Use \"help\" command to see the list of available commands.\n" << "Always use \"exit\" command when closing simplewallet to save\n" << "current session's state. Otherwise, you will possibly need to synchronize \n" << - "your wallet again. Your wallet key is NOT under risk anyway.\n" << - "**********************************************************************"; + "your wallet again. Your wallet key is NOT under risk anyway.\n" + ; + + if (!two_random) + { + success_msg_writer(true) << "\nPLEASE NOTE: the following 24 words can be used to recover access to your wallet. Please write them down and store them somewhere safe and secure. Please do not store them in your email or on file storage services outside of your immediate control. You will not be able to view these words again, so it is imperative to make note of them now.\n"; + std::cout << electrum_words << std::endl; + } + success_msg_writer() << "**********************************************************************"; + return true; } //---------------------------------------------------------------------------------------------------- @@ -916,6 +979,9 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_params, arg_daemon_port); command_line::add_arg(desc_params, arg_command); command_line::add_arg(desc_params, arg_log_level); + command_line::add_arg(desc_params, arg_restore_deterministic_wallet ); + command_line::add_arg(desc_params, arg_non_deterministic ); + command_line::add_arg(desc_params, arg_electrum_seed ); tools::wallet_rpc_server::init_options(desc_params); po::positional_options_description positional_options; diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index 3dcaaeaa0..006cdd08e 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -13,6 +13,7 @@ #include "wallet/wallet2.h" #include "console_handler.h" #include "password_container.h" +#include "crypto/crypto.h" // for definition of crypto::secret_key namespace cryptonote @@ -39,7 +40,7 @@ namespace cryptonote bool run_console_handler(); - bool new_wallet(const std::string &wallet_file, const std::string& password); + bool new_wallet(const std::string &wallet_file, const std::string& password, const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false, bool two_random = false); bool open_wallet(const std::string &wallet_file, const std::string& password); bool close_wallet(); @@ -125,6 +126,12 @@ namespace cryptonote std::string m_generate_new; std::string m_import_path; + std::string m_electrum_seed; // electrum-style seed parameter + + crypto::secret_key m_recovery_key; // recovery key (used as random for wallet gen) + bool m_restore_deterministic_wallet; // recover flag + bool m_non_deterministic; // old 2-random generation + std::string m_daemon_address; std::string m_daemon_host; int m_daemon_port; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index fb1e5575b..a63eb4be7 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -38,6 +38,7 @@ void do_prepare_file_names(const std::string& file_path, std::string& keys_file, keys_file += ".keys"; } } + } //namespace namespace tools @@ -435,7 +436,7 @@ void wallet2::load_keys(const std::string& keys_file_name, const std::string& pa THROW_WALLET_EXCEPTION_IF(!r, error::invalid_password); } //---------------------------------------------------------------------------------------------------- -void wallet2::generate(const std::string& wallet_, const std::string& password) +crypto::secret_key wallet2::generate(const std::string& wallet_, const std::string& password, const crypto::secret_key& recovery_param, bool recover, bool two_random) { clear(); prepare_file_names(wallet_); @@ -444,7 +445,8 @@ void wallet2::generate(const std::string& wallet_, const std::string& password) THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); - m_account.generate(); + crypto::secret_key retval = m_account.generate(recovery_param, recover, two_random); + m_account_public_address = m_account.get_keys().m_account_address; bool r = store_keys(m_keys_file, password); @@ -454,6 +456,7 @@ void wallet2::generate(const std::string& wallet_, const std::string& password) if(!r) LOG_PRINT_RED_L0("String with address text not saved"); store(); + return retval; } //---------------------------------------------------------------------------------------------------- void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists) diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 9ca586425..534a0517b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -97,7 +97,7 @@ namespace tools END_SERIALIZE() }; - void generate(const std::string& wallet, const std::string& password); + crypto::secret_key generate(const std::string& wallet, const std::string& password, const crypto::secret_key& recovery_param = crypto::secret_key(), bool recover = false, bool two_random = false); void load(const std::string& wallet, const std::string& password); void store(); cryptonote::account_base& get_account(){return m_account;} @@ -227,6 +227,7 @@ namespace boost namespace tools { + namespace detail { //---------------------------------------------------------------------------------------------------- diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index 0d42dbaf4..71c946545 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -188,6 +188,17 @@ namespace tools std::string to_string() const { return wallet_logic_error::to_string(); } }; + + //---------------------------------------------------------------------------------------------------- + struct invalid_pregenerated_random : public wallet_logic_error + { + explicit invalid_pregenerated_random (std::string&& loc) + : wallet_logic_error(std::move(loc), "invalid pregenerated random for wallet creation/recovery") + { + } + + std::string to_string() const { return wallet_logic_error::to_string(); } + }; //---------------------------------------------------------------------------------------------------- struct refresh_error : public wallet_logic_error { |