diff options
-rw-r--r-- | contrib/epee/include/net/levin_protocol_handler_async.h | 7 | ||||
-rw-r--r-- | contrib/epee/src/wipeable_string.cpp | 7 | ||||
-rw-r--r-- | src/cryptonote_basic/verification_context.h | 1 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_core.cpp | 2 | ||||
-rw-r--r-- | src/device/device_ledger.cpp | 70 | ||||
-rw-r--r-- | src/device/device_ledger.hpp | 44 | ||||
-rw-r--r-- | src/p2p/net_node.inl | 10 | ||||
-rw-r--r-- | src/rpc/core_rpc_server.cpp | 2 | ||||
-rw-r--r-- | src/rpc/core_rpc_server_commands_defs.h | 2 | ||||
-rw-r--r-- | src/rpc/daemon_handler.cpp | 5 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 6 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 2 | ||||
-rw-r--r-- | src/wallet/api/wallet2_api.h | 4 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.cpp | 5 | ||||
-rw-r--r-- | src/wallet/api/wallet_manager.h | 3 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 3 | ||||
-rw-r--r-- | tests/functional_tests/make_test_signature.cc | 22 | ||||
-rwxr-xr-x | tests/functional_tests/rpc_payment.py | 40 | ||||
-rwxr-xr-x | tests/functional_tests/transfer.py | 3 | ||||
-rw-r--r-- | tests/unit_tests/wipeable_string.cpp | 1 |
20 files changed, 201 insertions, 38 deletions
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h index 5774c0ba7..1341a4ae6 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/net/levin_protocol_handler_async.h @@ -949,7 +949,12 @@ bool async_protocol_handler_config<t_connection_context>::close(boost::uuids::uu { CRITICAL_REGION_LOCAL(m_connects_lock); async_protocol_handler<t_connection_context>* aph = find_connection(connection_id); - return 0 != aph ? aph->close() : false; + if (!aph) + return false; + if (!aph->close()) + return false; + m_connects.erase(connection_id); + return true; } //------------------------------------------------------------------------------------------ template<class t_connection_context> diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp index 4209b71bf..4928db172 100644 --- a/contrib/epee/src/wipeable_string.cpp +++ b/contrib/epee/src/wipeable_string.cpp @@ -188,13 +188,14 @@ void wipeable_string::split(std::vector<wipeable_string> &fields) const while (len--) { const char c = *ptr++; - if (c != ' ') + const bool space_prev = space; + space = std::isspace(c); + if (!space) { - if (space) + if (space_prev) fields.push_back({}); fields.back().push_back(c); } - space = c == ' '; } } diff --git a/src/cryptonote_basic/verification_context.h b/src/cryptonote_basic/verification_context.h index f5f663464..4d49b692c 100644 --- a/src/cryptonote_basic/verification_context.h +++ b/src/cryptonote_basic/verification_context.h @@ -47,7 +47,6 @@ namespace cryptonote bool m_too_big; bool m_overspend; bool m_fee_too_low; - bool m_not_rct; bool m_too_few_outputs; }; diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 212616af8..7fb232ad2 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1907,7 +1907,7 @@ namespace cryptonote MDEBUG("blocks in the last " << seconds[n] / 60 << " minutes: " << b << " (probability " << p << ")"); if (p < threshold) { - MWARNING("There were " << b << (b == max_blocks_checked ? " or more" : "") << " blocks in the last " << seconds[n] / 60 << " minutes, there might be large hash rate changes, or we might be partitioned, cut off from the Monero network or under attack. Or it could be just sheer bad luck."); + MWARNING("There were " << b << (b == max_blocks_checked ? " or more" : "") << " blocks in the last " << seconds[n] / 60 << " minutes, there might be large hash rate changes, or we might be partitioned, cut off from the Monero network or under attack, or your computer's time is off. Or it could be just sheer bad luck."); std::shared_ptr<tools::Notify> block_rate_notify = m_block_rate_notify; if (block_rate_notify) diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 49f54e5a5..eaa9f910d 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -55,7 +55,10 @@ namespace hw { } #define TRACKD MTRACE("hw") - #define ASSERT_SW(sw,ok,msk) CHECK_AND_ASSERT_THROW_MES(((sw)&(mask))==(ok), "Wrong Device Status : SW=" << std::hex << (sw) << " (EXPECT=" << std::hex << (ok) << ", MASK=" << std::hex << (mask) << ")") ; + #define ASSERT_SW(sw,ok,msk) CHECK_AND_ASSERT_THROW_MES(((sw)&(mask))==(ok), \ + "Wrong Device Status: " << "0x" << std::hex << (sw) << " (" << Status::to_string(sw) << "), " << \ + "EXPECTED 0x" << std::hex << (ok) << " (" << Status::to_string(ok) << "), " << \ + "MASK 0x" << std::hex << (mask)); #define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ; #define ASSERT_X(exp,msg) CHECK_AND_ASSERT_THROW_MES(exp, msg); @@ -64,6 +67,71 @@ namespace hw { crypto::secret_key dbg_spendkey; #endif + struct Status + { + unsigned int code; + const char *string; + + constexpr operator unsigned int() const + { + return this->code; + } + + static const char *to_string(unsigned int code); + }; + + // Must be sorted in ascending order by the code + #define LEDGER_STATUS(status) {status, #status} + constexpr Status status_codes[] = { + LEDGER_STATUS(SW_BYTES_REMAINING_00), + LEDGER_STATUS(SW_WARNING_STATE_UNCHANGED), + LEDGER_STATUS(SW_STATE_TERMINATED), + LEDGER_STATUS(SW_MORE_DATA_AVAILABLE), + LEDGER_STATUS(SW_WRONG_LENGTH), + LEDGER_STATUS(SW_LOGICAL_CHANNEL_NOT_SUPPORTED), + LEDGER_STATUS(SW_SECURE_MESSAGING_NOT_SUPPORTED), + LEDGER_STATUS(SW_LAST_COMMAND_EXPECTED), + LEDGER_STATUS(SW_COMMAND_CHAINING_NOT_SUPPORTED), + LEDGER_STATUS(SW_SECURITY_LOAD_KEY), + LEDGER_STATUS(SW_SECURITY_COMMITMENT_CONTROL), + LEDGER_STATUS(SW_SECURITY_AMOUNT_CHAIN_CONTROL), + LEDGER_STATUS(SW_SECURITY_COMMITMENT_CHAIN_CONTROL), + LEDGER_STATUS(SW_SECURITY_OUTKEYS_CHAIN_CONTROL), + LEDGER_STATUS(SW_SECURITY_MAXOUTPUT_REACHED), + LEDGER_STATUS(SW_SECURITY_TRUSTED_INPUT), + LEDGER_STATUS(SW_CLIENT_NOT_SUPPORTED), + LEDGER_STATUS(SW_SECURITY_STATUS_NOT_SATISFIED), + LEDGER_STATUS(SW_FILE_INVALID), + LEDGER_STATUS(SW_PIN_BLOCKED), + LEDGER_STATUS(SW_DATA_INVALID), + LEDGER_STATUS(SW_CONDITIONS_NOT_SATISFIED), + LEDGER_STATUS(SW_COMMAND_NOT_ALLOWED), + LEDGER_STATUS(SW_APPLET_SELECT_FAILED), + LEDGER_STATUS(SW_WRONG_DATA), + LEDGER_STATUS(SW_FUNC_NOT_SUPPORTED), + LEDGER_STATUS(SW_FILE_NOT_FOUND), + LEDGER_STATUS(SW_RECORD_NOT_FOUND), + LEDGER_STATUS(SW_FILE_FULL), + LEDGER_STATUS(SW_INCORRECT_P1P2), + LEDGER_STATUS(SW_REFERENCED_DATA_NOT_FOUND), + LEDGER_STATUS(SW_WRONG_P1P2), + LEDGER_STATUS(SW_CORRECT_LENGTH_00), + LEDGER_STATUS(SW_INS_NOT_SUPPORTED), + LEDGER_STATUS(SW_CLA_NOT_SUPPORTED), + LEDGER_STATUS(SW_UNKNOWN), + LEDGER_STATUS(SW_OK), + LEDGER_STATUS(SW_ALGORITHM_UNSUPPORTED) + }; + + const char *Status::to_string(unsigned int code) + { + constexpr size_t status_codes_size = sizeof(status_codes) / sizeof(status_codes[0]); + constexpr const Status *status_codes_end = &status_codes[status_codes_size]; + + const Status *item = std::lower_bound(&status_codes[0], status_codes_end, code); + return (item == status_codes_end || code < *item) ? "UNKNOWN" : item->string; + } + /* ===================================================================== */ /* === hmacmap ==== */ /* ===================================================================== */ diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 05a26143a..e3e30fba8 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -58,6 +58,46 @@ namespace hw { #ifdef WITH_DEVICE_LEDGER + // Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h + #define SW_BYTES_REMAINING_00 0x6100 + #define SW_WARNING_STATE_UNCHANGED 0x6200 + #define SW_STATE_TERMINATED 0x6285 + #define SW_MORE_DATA_AVAILABLE 0x6310 + #define SW_WRONG_LENGTH 0x6700 + #define SW_LOGICAL_CHANNEL_NOT_SUPPORTED 0x6881 + #define SW_SECURE_MESSAGING_NOT_SUPPORTED 0x6882 + #define SW_LAST_COMMAND_EXPECTED 0x6883 + #define SW_COMMAND_CHAINING_NOT_SUPPORTED 0x6884 + #define SW_SECURITY_LOAD_KEY 0x6900 + #define SW_SECURITY_COMMITMENT_CONTROL 0x6911 + #define SW_SECURITY_AMOUNT_CHAIN_CONTROL 0x6912 + #define SW_SECURITY_COMMITMENT_CHAIN_CONTROL 0x6913 + #define SW_SECURITY_OUTKEYS_CHAIN_CONTROL 0x6914 + #define SW_SECURITY_MAXOUTPUT_REACHED 0x6915 + #define SW_SECURITY_TRUSTED_INPUT 0x6916 + #define SW_CLIENT_NOT_SUPPORTED 0x6930 + #define SW_SECURITY_STATUS_NOT_SATISFIED 0x6982 + #define SW_FILE_INVALID 0x6983 + #define SW_PIN_BLOCKED 0x6983 + #define SW_DATA_INVALID 0x6984 + #define SW_CONDITIONS_NOT_SATISFIED 0x6985 + #define SW_COMMAND_NOT_ALLOWED 0x6986 + #define SW_APPLET_SELECT_FAILED 0x6999 + #define SW_WRONG_DATA 0x6a80 + #define SW_FUNC_NOT_SUPPORTED 0x6a81 + #define SW_FILE_NOT_FOUND 0x6a82 + #define SW_RECORD_NOT_FOUND 0x6a83 + #define SW_FILE_FULL 0x6a84 + #define SW_INCORRECT_P1P2 0x6a86 + #define SW_REFERENCED_DATA_NOT_FOUND 0x6a88 + #define SW_WRONG_P1P2 0x6b00 + #define SW_CORRECT_LENGTH_00 0x6c00 + #define SW_INS_NOT_SUPPORTED 0x6d00 + #define SW_CLA_NOT_SUPPORTED 0x6e00 + #define SW_UNKNOWN 0x6f00 + #define SW_OK 0x9000 + #define SW_ALGORITHM_UNSUPPORTED 0x9484 + namespace { bool apdu_verbose =true; } @@ -128,8 +168,8 @@ namespace hw { unsigned int id; void logCMD(void); void logRESP(void); - unsigned int exchange(unsigned int ok=0x9000, unsigned int mask=0xFFFF); - unsigned int exchange_wait_on_input(unsigned int ok=0x9000, unsigned int mask=0xFFFF); + unsigned int exchange(unsigned int ok=SW_OK, unsigned int mask=0xFFFF); + unsigned int exchange_wait_on_input(unsigned int ok=SW_OK, unsigned int mask=0xFFFF); void reset_buffer(void); int set_command_header(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00); int set_command_header_noopt(unsigned char ins, unsigned char p1 = 0x00, unsigned char p2 = 0x00); diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 9b6358dee..dcd16e5c1 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -1013,15 +1013,18 @@ namespace nodetool epee::simple_event ev; std::atomic<bool> hsh_result(false); + bool timeout = false; bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_HANDSHAKE::response>(context_, COMMAND_HANDSHAKE::ID, arg, zone.m_net_server.get_config_object(), - [this, &pi, &ev, &hsh_result, &just_take_peerlist, &context_](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context) + [this, &pi, &ev, &hsh_result, &just_take_peerlist, &context_, &timeout](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context) { epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ev.raise();}); if(code < 0) { LOG_WARNING_CC(context, "COMMAND_HANDSHAKE invoke failed. (" << code << ", " << epee::levin::get_err_descr(code) << ")"); + if (code == LEVIN_ERROR_CONNECTION_TIMEDOUT || code == LEVIN_ERROR_CONNECTION_DESTROYED) + timeout = true; return; } @@ -1079,7 +1082,8 @@ namespace nodetool if(!hsh_result) { LOG_WARNING_CC(context_, "COMMAND_HANDSHAKE Failed"); - m_network_zones.at(context_.m_remote_address.get_zone()).m_net_server.get_config_object().close(context_.m_connection_id); + if (!timeout) + zone.m_net_server.get_config_object().close(context_.m_connection_id); } else if (!just_take_peerlist) { @@ -1266,7 +1270,6 @@ namespace nodetool LOG_PRINT_CC_PRIORITY_NODE(is_priority, *con, "Failed to HANDSHAKE with peer " << na.str() /*<< ", try " << try_count*/); - zone.m_net_server.get_config_object().close(con->m_connection_id); record_addr_failed(na); return false; } @@ -1330,7 +1333,6 @@ namespace nodetool bool is_priority = is_priority_node(na); LOG_PRINT_CC_PRIORITY_NODE(is_priority, *con, "Failed to HANDSHAKE with peer " << na.str()); - zone.m_net_server.get_config_object().close(con->m_connection_id); record_addr_failed(na); return false; } diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index 8e5207e82..d33dbd16a 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -1134,8 +1134,6 @@ namespace cryptonote add_reason(reason, "overspend"); if ((res.fee_too_low = tvc.m_fee_too_low)) add_reason(reason, "fee too low"); - if ((res.not_rct = tvc.m_not_rct)) - add_reason(reason, "tx is not ringct"); if ((res.too_few_outputs = tvc.m_too_few_outputs)) add_reason(reason, "too few outputs"); const std::string punctuation = reason.empty() ? "" : ": "; diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index dbb1d4472..a3c187c24 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -588,7 +588,6 @@ namespace cryptonote bool too_big; bool overspend; bool fee_too_low; - bool not_rct; bool too_few_outputs; bool sanity_check_failed; @@ -603,7 +602,6 @@ namespace cryptonote KV_SERIALIZE(too_big) KV_SERIALIZE(overspend) KV_SERIALIZE(fee_too_low) - KV_SERIALIZE(not_rct) KV_SERIALIZE(too_few_outputs) KV_SERIALIZE(sanity_check_failed) END_KV_SERIALIZE_MAP() diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 125688ba5..7292176b4 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -410,11 +410,6 @@ namespace rpc if (!res.error_details.empty()) res.error_details += " and "; res.error_details += "fee too low"; } - if (tvc.m_not_rct) - { - if (!res.error_details.empty()) res.error_details += " and "; - res.error_details += "tx is not ringct"; - } if (tvc.m_too_few_outputs) { if (!res.error_details.empty()) res.error_details += " and "; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 33047f703..4612b0397 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -725,7 +725,7 @@ bool WalletImpl::recover(const std::string &path, const std::string &seed) return recover(path, "", seed); } -bool WalletImpl::recover(const std::string &path, const std::string &password, const std::string &seed) +bool WalletImpl::recover(const std::string &path, const std::string &password, const std::string &seed, const std::string &seed_offset/* = {}*/) { clearStatus(); m_errorString.clear(); @@ -743,6 +743,10 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c setStatusError(tr("Electrum-style word list failed verification")); return false; } + if (!seed_offset.empty()) + { + recovery_key = cryptonote::decrypt_key(recovery_key, seed_offset); + } if (old_language == crypto::ElectrumWords::old_language_name) old_language = Language::English().get_language_name(); diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index e46a62340..66eeb0e73 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -60,7 +60,7 @@ public: const std::string &language) const override; bool open(const std::string &path, const std::string &password); bool recover(const std::string &path,const std::string &password, - const std::string &seed); + const std::string &seed, const std::string &seed_offset = {}); bool recoverFromKeysWithPassword(const std::string &path, const std::string &password, const std::string &language, diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 3945e55c9..09c64106e 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -1093,10 +1093,12 @@ struct WalletManager * \param nettype Network type * \param restoreHeight restore from start height * \param kdf_rounds Number of rounds for key derivation function + * \param seed_offset Seed offset passphrase (optional) * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) */ virtual Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic, - NetworkType nettype = MAINNET, uint64_t restoreHeight = 0, uint64_t kdf_rounds = 1) = 0; + NetworkType nettype = MAINNET, uint64_t restoreHeight = 0, uint64_t kdf_rounds = 1, + const std::string &seed_offset = {}) = 0; Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic, bool testnet = false, uint64_t restoreHeight = 0) // deprecated { diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index d589dcc75..44a184304 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -93,13 +93,14 @@ Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight, - uint64_t kdf_rounds) + uint64_t kdf_rounds, + const std::string &seed_offset/* = {}*/) { WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds); if(restoreHeight > 0){ wallet->setRefreshFromBlockHeight(restoreHeight); } - wallet->recover(path, password, mnemonic); + wallet->recover(path, password, mnemonic, seed_offset); return wallet; } diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h index 537fc5ba6..0595b8327 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -46,7 +46,8 @@ public: const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight, - uint64_t kdf_rounds = 1) override; + uint64_t kdf_rounds = 1, + const std::string &seed_offset = {}) override; virtual Wallet * createWalletFromKeys(const std::string &path, const std::string &password, const std::string &language, diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 90682e60c..70ceddad3 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -236,8 +236,6 @@ namespace add_reason(reason, "overspend"); if (res.fee_too_low) add_reason(reason, "fee too low"); - if (res.not_rct) - add_reason(reason, "tx is not ringct"); if (res.sanity_check_failed) add_reason(reason, "tx sanity check failed"); if (res.not_relayed) @@ -437,6 +435,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl verification_required && !ssl_options.has_strong_verification(real_daemon), tools::error::wallet_internal_error, tools::wallet2::tr("Enabling --") + std::string{use_proxy ? opts.proxy.name : opts.daemon_ssl.name} + tools::wallet2::tr(" requires --") + + opts.daemon_ssl_allow_any_cert.name + tools::wallet2::tr(" or --") + opts.daemon_ssl_ca_certificates.name + tools::wallet2::tr(" or --") + opts.daemon_ssl_allowed_fingerprints.name + tools::wallet2::tr(" or use of a .onion/.i2p domain") ); } diff --git a/tests/functional_tests/make_test_signature.cc b/tests/functional_tests/make_test_signature.cc index 789523de5..6ac1a6a86 100644 --- a/tests/functional_tests/make_test_signature.cc +++ b/tests/functional_tests/make_test_signature.cc @@ -33,9 +33,9 @@ int main(int argc, const char **argv) { TRY_ENTRY(); - if (argc > 2) + if (argc > 3) { - fprintf(stderr, "usage: %s <secret_key>\n", argv[0]); + fprintf(stderr, "usage: %s [<secret_key> [N]]\n", argv[0]); return 1; } @@ -55,8 +55,22 @@ int main(int argc, const char **argv) fprintf(stderr, "invalid secret key\n"); return 1; } - std::string signature = cryptonote::make_rpc_payment_signature(skey); - printf("%s\n", signature.c_str()); + uint32_t count = 1; + if (argc == 3) + { + int i = atoi(argv[2]); + if (i <= 0) + { + fprintf(stderr, "invalid count\n"); + return 1; + } + count = (uint32_t)i; + } + while (count--) + { + std::string signature = cryptonote::make_rpc_payment_signature(skey); + printf("%s\n", signature.c_str()); + } return 0; CATCH_ENTRY_L0("main()", 1); } diff --git a/tests/functional_tests/rpc_payment.py b/tests/functional_tests/rpc_payment.py index 4c777ccd7..3bf995f0c 100755 --- a/tests/functional_tests/rpc_payment.py +++ b/tests/functional_tests/rpc_payment.py @@ -31,6 +31,7 @@ from __future__ import print_function import subprocess import os +import time """Test daemon RPC payment calls """ @@ -43,6 +44,7 @@ class RPCPaymentTest(): self.make_test_signature = os.environ['MAKE_TEST_SIGNATURE'] assert len(self.make_test_signature) > 0 self.secret_key, self.public_key = self.get_keys() + self.signatures = [] self.reset() self.test_access_tracking() self.test_access_mining() @@ -56,8 +58,17 @@ class RPCPaymentTest(): assert len(fields) == 2 return fields + def refill_signatures(self): + signatures = subprocess.check_output([self.make_test_signature, self.secret_key, '256']).decode('utf-8') + for line in signatures.split(): + self.signatures.append(line.rstrip()) + def get_signature(self): - return subprocess.check_output([self.make_test_signature, self.secret_key]).decode('utf-8').rstrip() + if len(self.signatures) == 0: + self.refill_signatures() + s = self.signatures[0] + self.signatures = self.signatures[1:] + return s def reset(self): print('Resetting blockchain') @@ -143,6 +154,7 @@ class RPCPaymentTest(): found_valid = 0 found_invalid = 0 last_credits = 0 + loop_time = time.time() while found_valid == 0 or found_invalid == 0: nonce += 1 try: @@ -152,10 +164,17 @@ class RPCPaymentTest(): except Exception as e: found_invalid += 1 res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() assert res.credits < last_credits or res.credits == 0 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails last_credits = res.credits + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() + # we should now have 1 valid nonce, and a number of bad ones res = daemon.rpc_access_info(client = self.get_signature()) assert len(res.hashing_blob) > 39 @@ -176,6 +195,7 @@ class RPCPaymentTest(): assert e.nonces_dupe == 0 # Try random nonces till we find one that's valid so we get a load of credits + loop_time = time.time() while last_credits == 0: nonce += 1 try: @@ -186,6 +206,10 @@ class RPCPaymentTest(): except: found_invalid += 1 assert nonce < 1000 # can't find a valid none -> the RPC probably fails + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() # we should now have at least 5000 res = daemon.rpc_access_info(client = self.get_signature()) @@ -208,6 +232,7 @@ class RPCPaymentTest(): res = daemon.rpc_access_info(client = self.get_signature()) cookie = res.cookie old_cookie = cookie # we keep that so can submit a stale later + loop_time = time.time() while True: nonce += 1 try: @@ -218,6 +243,11 @@ class RPCPaymentTest(): found_invalid += 1 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie + loop_time = time.time() + res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] @@ -247,14 +277,17 @@ class RPCPaymentTest(): # find stales without updating cookie, one within 5 seconds (accepted), one later (rejected) res = daemon.rpc_access_info(client = self.get_signature()) + cookie = res.cookie # let the daemon update its timestamp, but use old cookie found_close_stale = 0 found_late_stale = 0 + loop_time = time.time() while found_close_stale == 0 or found_late_stale == 0: nonce += 1 try: res = daemon.rpc_access_submit_nonce(nonce = nonce, cookie = cookie, client = self.get_signature()) found_close_stale += 1 found_valid += 1 + time.sleep(15) # now we've got an early stale, wait till they become late stales except Exception as e: #if e[0]['error']['code'] == -18: # stale if "'code': -18" in str(e): # stale (ugly version, but also works with python 3) @@ -263,6 +296,11 @@ class RPCPaymentTest(): found_invalid += 1 assert nonce < 1000 # can't find both valid and invalid -> the RPC probably fails + if time.time() >= loop_time + 10: + res = daemon.rpc_access_info(client = self.get_signature()) + # cookie = res.cookie # let the daemon update its timestamp, but use old cookie + loop_time = time.time() + res = daemon.rpc_access_data() assert len(res.entries) > 0 e = [x for x in res.entries if x['client'] == self.public_key] diff --git a/tests/functional_tests/transfer.py b/tests/functional_tests/transfer.py index 3bed69b98..c3d71aa9c 100755 --- a/tests/functional_tests/transfer.py +++ b/tests/functional_tests/transfer.py @@ -256,7 +256,6 @@ class TransferTest(): assert res.too_big == False assert res.overspend == False assert res.fee_too_low == False - assert res.not_rct == False self.wallet[0].refresh() @@ -598,7 +597,6 @@ class TransferTest(): assert res.too_big == False assert res.overspend == False assert res.fee_too_low == False - assert res.not_rct == False res = daemon.get_transactions([txes[0][0]]) assert len(res.txs) >= 1 @@ -615,7 +613,6 @@ class TransferTest(): assert res.too_big == False assert res.overspend == False assert res.fee_too_low == False - assert res.not_rct == False assert res.too_few_outputs == False res = daemon.get_transactions([txes[0][0]]) diff --git a/tests/unit_tests/wipeable_string.cpp b/tests/unit_tests/wipeable_string.cpp index 44e050c5c..9911bd6f4 100644 --- a/tests/unit_tests/wipeable_string.cpp +++ b/tests/unit_tests/wipeable_string.cpp @@ -182,6 +182,7 @@ TEST(wipeable_string, split) ASSERT_TRUE(check_split(" foo bar baz ", {"foo", "bar", "baz"})); ASSERT_TRUE(check_split(" foo bar baz", {"foo", "bar", "baz"})); ASSERT_TRUE(check_split("foo bar baz ", {"foo", "bar", "baz"})); + ASSERT_TRUE(check_split("\tfoo\n bar\r\nbaz", {"foo", "bar", "baz"})); } TEST(wipeable_string, parse_hexstr) |