diff options
Diffstat (limited to 'src')
44 files changed, 2531 insertions, 1255 deletions
diff --git a/src/.clang-tidy b/src/.clang-tidy index 8fcb30c8f8..9d78ccc959 100644 --- a/src/.clang-tidy +++ b/src/.clang-tidy @@ -6,6 +6,7 @@ misc-unused-using-decls, modernize-use-default-member-init, modernize-use-nullptr, performance-for-range-copy, +performance-move-const-arg, performance-unnecessary-copy-initialization, readability-redundant-declaration, readability-redundant-string-init, @@ -17,7 +18,11 @@ misc-unused-using-decls, modernize-use-default-member-init, modernize-use-nullptr, performance-for-range-copy, +performance-move-const-arg, performance-unnecessary-copy-initialization, readability-redundant-declaration, readability-redundant-string-init, ' +CheckOptions: + - key: performance-move-const-arg.CheckTriviallyCopyableMove + value: false diff --git a/src/blockfilter.h b/src/blockfilter.h index d6a51e95c2..0cb627d9df 100644 --- a/src/blockfilter.h +++ b/src/blockfilter.h @@ -11,6 +11,7 @@ #include <unordered_set> #include <vector> +#include <attributes.h> #include <primitives/block.h> #include <serialize.h> #include <uint256.h> @@ -65,8 +66,8 @@ public: GCSFilter(const Params& params, const ElementSet& elements); uint32_t GetN() const { return m_N; } - const Params& GetParams() const { return m_params; } - const std::vector<unsigned char>& GetEncoded() const { return m_encoded; } + const Params& GetParams() const LIFETIMEBOUND { return m_params; } + const std::vector<unsigned char>& GetEncoded() const LIFETIMEBOUND { return m_encoded; } /** * Checks if the element may be in the set. False positives are possible @@ -128,10 +129,10 @@ public: BlockFilter(BlockFilterType filter_type, const CBlock& block, const CBlockUndo& block_undo); BlockFilterType GetFilterType() const { return m_filter_type; } - const uint256& GetBlockHash() const { return m_block_hash; } - const GCSFilter& GetFilter() const { return m_filter; } + const uint256& GetBlockHash() const LIFETIMEBOUND { return m_block_hash; } + const GCSFilter& GetFilter() const LIFETIMEBOUND { return m_filter; } - const std::vector<unsigned char>& GetEncodedFilter() const + const std::vector<unsigned char>& GetEncodedFilter() const LIFETIMEBOUND { return m_filter.GetEncoded(); } diff --git a/src/chain.cpp b/src/chain.cpp index 19c35b5012..66a0830394 100644 --- a/src/chain.cpp +++ b/src/chain.cpp @@ -49,7 +49,7 @@ std::vector<uint256> LocatorEntries(const CBlockIndex* index) CBlockLocator GetLocator(const CBlockIndex* index) { - return CBlockLocator{std::move(LocatorEntries(index))}; + return CBlockLocator{LocatorEntries(index)}; } CBlockLocator CChain::GetLocator() const diff --git a/src/hash.cpp b/src/hash.cpp index 111b707964..06caaac6ee 100644 --- a/src/hash.cpp +++ b/src/hash.cpp @@ -16,7 +16,7 @@ inline uint32_t ROTL32(uint32_t x, int8_t r) unsigned int MurmurHash3(unsigned int nHashSeed, Span<const unsigned char> vDataToHash) { - // The following is MurmurHash3 (x86_32), see https://code.google.com/p/smhasher/source/browse/trunk/MurmurHash3.cpp + // The following is MurmurHash3 (x86_32), see https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp uint32_t h1 = nHashSeed; const uint32_t c1 = 0xcc9e2d51; const uint32_t c2 = 0x1b873593; diff --git a/src/headerssync.cpp b/src/headerssync.cpp index 3eca492d81..757b942cd9 100644 --- a/src/headerssync.cpp +++ b/src/headerssync.cpp @@ -42,7 +42,7 @@ HeadersSyncState::HeadersSyncState(NodeId id, const Consensus::Params& consensus // could try again, if necessary, to sync a longer chain). m_max_commitments = 6*(Ticks<std::chrono::seconds>(GetAdjustedTime() - NodeSeconds{std::chrono::seconds{chain_start->GetMedianTimePast()}}) + MAX_FUTURE_BLOCK_TIME) / HEADER_COMMITMENT_PERIOD; - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync started with peer=%d: height=%i, max_commitments=%i, min_work=%s\n", m_id, m_current_height, m_max_commitments, m_minimum_required_work.ToString()); + LogPrint(BCLog::NET, "Initial headers sync started with peer=%d: height=%i, max_commitments=%i, min_work=%s\n", m_id, m_current_height, m_max_commitments, m_minimum_required_work.ToString()); } /** Free any memory in use, and mark this object as no longer usable. This is @@ -92,7 +92,7 @@ HeadersSyncState::ProcessingResult HeadersSyncState::ProcessNextHeaders(const // If we're in PRESYNC and we get a non-full headers // message, then the peer's chain has ended and definitely doesn't // have enough work, so we can stop our sync. - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: incomplete headers message at height=%i (presync phase)\n", m_id, m_current_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: incomplete headers message at height=%i (presync phase)\n", m_id, m_current_height); } } } else if (m_download_state == State::REDOWNLOAD) { @@ -118,7 +118,7 @@ HeadersSyncState::ProcessingResult HeadersSyncState::ProcessNextHeaders(const // If we hit our target blockhash, then all remaining headers will be // returned and we can clear any leftover internal state. if (m_redownloaded_headers.empty() && m_process_all_remaining_headers) { - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync complete with peer=%d: releasing all at height=%i (redownload phase)\n", m_id, m_redownload_buffer_last_height); + LogPrint(BCLog::NET, "Initial headers sync complete with peer=%d: releasing all at height=%i (redownload phase)\n", m_id, m_redownload_buffer_last_height); } else if (full_headers_message) { // If the headers message is full, we need to request more. ret.request_more = true; @@ -127,7 +127,7 @@ HeadersSyncState::ProcessingResult HeadersSyncState::ProcessNextHeaders(const // declining to serve us that full chain again. Give up. // Note that there's no more processing to be done with these // headers, so we can still return success. - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: incomplete headers message at height=%i (redownload phase)\n", m_id, m_redownload_buffer_last_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: incomplete headers message at height=%i (redownload phase)\n", m_id, m_redownload_buffer_last_height); } } } @@ -150,7 +150,7 @@ bool HeadersSyncState::ValidateAndStoreHeadersCommitments(const std::vector<CBlo // This might be benign -- perhaps our peer reorged away from the chain // they were on. Give up on this sync for now (likely we will start a // new sync with a new starting point). - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: non-continuous headers at height=%i (presync phase)\n", m_id, m_current_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: non-continuous headers at height=%i (presync phase)\n", m_id, m_current_height); return false; } @@ -169,7 +169,7 @@ bool HeadersSyncState::ValidateAndStoreHeadersCommitments(const std::vector<CBlo m_redownload_buffer_last_hash = m_chain_start->GetBlockHash(); m_redownload_chain_work = m_chain_start->nChainWork; m_download_state = State::REDOWNLOAD; - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync transition with peer=%d: reached sufficient work at height=%i, redownloading from height=%i\n", m_id, m_current_height, m_redownload_buffer_last_height); + LogPrint(BCLog::NET, "Initial headers sync transition with peer=%d: reached sufficient work at height=%i, redownloading from height=%i\n", m_id, m_current_height, m_redownload_buffer_last_height); } return true; } @@ -188,7 +188,7 @@ bool HeadersSyncState::ValidateAndProcessSingleHeader(const CBlockHeader& curren // adjustment maximum. if (!PermittedDifficultyTransition(m_consensus_params, next_height, m_last_header_received.nBits, current.nBits)) { - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: invalid difficulty transition at height=%i (presync phase)\n", m_id, next_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: invalid difficulty transition at height=%i (presync phase)\n", m_id, next_height); return false; } @@ -200,7 +200,7 @@ bool HeadersSyncState::ValidateAndProcessSingleHeader(const CBlockHeader& curren // It's possible the chain grew since we started the sync; so // potentially we could succeed in syncing the peer's chain if we // try again later. - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: exceeded max commitments at height=%i (presync phase)\n", m_id, next_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: exceeded max commitments at height=%i (presync phase)\n", m_id, next_height); return false; } } @@ -222,7 +222,7 @@ bool HeadersSyncState::ValidateAndStoreRedownloadedHeader(const CBlockHeader& he // Ensure that we're working on a header that connects to the chain we're // downloading. if (header.hashPrevBlock != m_redownload_buffer_last_hash) { - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: non-continuous headers at height=%i (redownload phase)\n", m_id, next_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: non-continuous headers at height=%i (redownload phase)\n", m_id, next_height); return false; } @@ -236,7 +236,7 @@ bool HeadersSyncState::ValidateAndStoreRedownloadedHeader(const CBlockHeader& he if (!PermittedDifficultyTransition(m_consensus_params, next_height, previous_nBits, header.nBits)) { - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: invalid difficulty transition at height=%i (redownload phase)\n", m_id, next_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: invalid difficulty transition at height=%i (redownload phase)\n", m_id, next_height); return false; } @@ -255,7 +255,7 @@ bool HeadersSyncState::ValidateAndStoreRedownloadedHeader(const CBlockHeader& he // target blockhash just because we ran out of commitments. if (!m_process_all_remaining_headers && next_height % HEADER_COMMITMENT_PERIOD == m_commit_offset) { if (m_header_commitments.size() == 0) { - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: commitment overrun at height=%i (redownload phase)\n", m_id, next_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: commitment overrun at height=%i (redownload phase)\n", m_id, next_height); // Somehow our peer managed to feed us a different chain and // we've run out of commitments. return false; @@ -264,7 +264,7 @@ bool HeadersSyncState::ValidateAndStoreRedownloadedHeader(const CBlockHeader& he bool expected_commitment = m_header_commitments.front(); m_header_commitments.pop_front(); if (commitment != expected_commitment) { - LogPrint(BCLog::HEADERSSYNC, "Initial headers sync aborted with peer=%d: commitment mismatch at height=%i (redownload phase)\n", m_id, next_height); + LogPrint(BCLog::NET, "Initial headers sync aborted with peer=%d: commitment mismatch at height=%i (redownload phase)\n", m_id, next_height); return false; } } diff --git a/src/index/blockfilterindex.h b/src/index/blockfilterindex.h index 968eccb6b3..a31f7e460e 100644 --- a/src/index/blockfilterindex.h +++ b/src/index/blockfilterindex.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_INDEX_BLOCKFILTERINDEX_H #define BITCOIN_INDEX_BLOCKFILTERINDEX_H +#include <attributes.h> #include <blockfilter.h> #include <chain.h> #include <flatfile.h> @@ -49,9 +50,9 @@ protected: bool CustomRewind(const interfaces::BlockKey& current_tip, const interfaces::BlockKey& new_tip) override; - BaseIndex::DB& GetDB() const override { return *m_db; } + BaseIndex::DB& GetDB() const LIFETIMEBOUND override { return *m_db; } - const char* GetName() const override { return m_name.c_str(); } + const char* GetName() const LIFETIMEBOUND override { return m_name.c_str(); } public: /** Constructs the index, which becomes available to be queried. */ diff --git a/src/init.cpp b/src/init.cpp index 137d98026e..f3cb763ecc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -742,7 +742,7 @@ namespace { // Variables internal to initialization process only int nMaxConnections; int nUserMaxConnections; int nFD; -ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK | NODE_NETWORK_LIMITED | NODE_WITNESS); +ServiceFlags nLocalServices = ServiceFlags(NODE_NETWORK_LIMITED | NODE_WITNESS); int64_t peer_connect_timeout; std::set<BlockFilterType> g_enabled_filter_types; @@ -915,15 +915,12 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb // ********************************************************* Step 3: parameter-to-internal-flags init::SetLoggingCategories(args); + init::SetLoggingLevel(args); fCheckBlockIndex = args.GetBoolArg("-checkblockindex", chainparams.DefaultConsistencyChecks()); fCheckpointsEnabled = args.GetBoolArg("-checkpoints", DEFAULT_CHECKPOINTS_ENABLED); hashAssumeValid = uint256S(args.GetArg("-assumevalid", chainparams.GetConsensus().defaultAssumeValid.GetHex())); - if (!hashAssumeValid.IsNull()) - LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex()); - else - LogPrintf("Validating signatures for all blocks.\n"); if (args.IsArgSet("-minimumchainwork")) { const std::string minChainWorkStr = args.GetArg("-minimumchainwork", ""); @@ -934,10 +931,6 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb } else { nMinimumChainWork = UintToArith256(chainparams.GetConsensus().nMinimumChainWork); } - LogPrintf("Setting nMinimumChainWork=%s\n", nMinimumChainWork.GetHex()); - if (nMinimumChainWork < UintToArith256(chainparams.GetConsensus().nMinimumChainWork)) { - LogPrintf("Warning: nMinimumChainWork set below default value of %s\n", chainparams.GetConsensus().nMinimumChainWork.GetHex()); - } // block pruning; get the amount of disk space (in MiB) to allot for block & undo files int64_t nPruneArg = args.GetIntArg("-prune", 0); @@ -946,14 +939,12 @@ bool AppInitParameterInteraction(const ArgsManager& args, bool use_syscall_sandb } nPruneTarget = (uint64_t) nPruneArg * 1024 * 1024; if (nPruneArg == 1) { // manual pruning: -prune=1 - LogPrintf("Block pruning enabled. Use RPC call pruneblockchain(height) to manually prune block and undo files.\n"); nPruneTarget = std::numeric_limits<uint64_t>::max(); fPruneMode = true; } else if (nPruneTarget) { if (nPruneTarget < MIN_DISK_SPACE_FOR_BLOCK_FILES) { return InitError(strprintf(_("Prune configured below the minimum of %d MiB. Please use a higher number."), MIN_DISK_SPACE_FOR_BLOCK_FILES / 1024 / 1024)); } - LogPrintf("Prune configured to target %u MiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024); fPruneMode = true; } @@ -1519,11 +1510,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) // ********************************************************* Step 10: data directory maintenance - // if pruning, unset the service bit and perform the initial blockstore prune + // if pruning, perform the initial blockstore prune // after any wallet rescanning has taken place. if (fPruneMode) { - LogPrintf("Unsetting NODE_NETWORK on prune mode\n"); - nLocalServices = ServiceFlags(nLocalServices & ~NODE_NETWORK); if (!fReindex) { LOCK(cs_main); for (CChainState* chainstate : chainman.GetAll()) { @@ -1531,6 +1520,9 @@ bool AppInitMain(NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip_info) chainstate->PruneAndFlush(); } } + } else { + LogPrintf("Setting NODE_NETWORK on non-prune mode\n"); + nLocalServices = ServiceFlags(nLocalServices | NODE_NETWORK); } // ********************************************************* Step 11: import blocks diff --git a/src/init/common.cpp b/src/init/common.cpp index bdd7f16307..f2d2c5640a 100644 --- a/src/init/common.cpp +++ b/src/init/common.cpp @@ -11,6 +11,7 @@ #include <logging.h> #include <node/interface_ui.h> #include <tinyformat.h> +#include <util/string.h> #include <util/system.h> #include <util/time.h> #include <util/translation.h> @@ -23,11 +24,12 @@ namespace init { void AddLoggingArgs(ArgsManager& argsman) { argsman.AddArg("-debuglogfile=<file>", strprintf("Specify location of debug log file. Relative paths will be prefixed by a net-specific datadir location. (-nodebuglogfile to disable; default: %s)", DEFAULT_DEBUGLOGFILE), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - argsman.AddArg("-debug=<category>", "Output debugging information (default: -nodebug, supplying <category> is optional). " - "If <category> is not supplied or if <category> = 1, output all debugging information. <category> can be: " + LogInstance().LogCategoriesString() + ". This option can be specified multiple times to output multiple categories.", + argsman.AddArg("-debug=<category>", "Output debug and trace logging (default: -nodebug, supplying <category> is optional). " + "If <category> is not supplied or if <category> = 1, output all debug and trace logging. <category> can be: " + LogInstance().LogCategoriesString() + ". This option can be specified multiple times to output multiple categories.", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); - argsman.AddArg("-debugexclude=<category>", "Exclude debugging information for a category. Can be used in conjunction with -debug=1 to output debug logs for all categories except the specified category. This option can be specified multiple times to exclude multiple categories.", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-debugexclude=<category>", "Exclude debug and trace logging for a category. Can be used in conjunction with -debug=1 to output debug and trace logging for all categories except the specified category. This option can be specified multiple times to exclude multiple categories.", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logips", strprintf("Include IP addresses in debug output (default: %u)", DEFAULT_LOGIPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + argsman.AddArg("-loglevel=<level>|<category>:<level>", strprintf("Set the global or per-category severity level for logging categories enabled with the -debug configuration option or the logging RPC: %s (default=%s); warning and error levels are always logged. If <category>:<level> is supplied, the setting will override the global one and may be specified multiple times to set multiple category-specific levels. <category> can be: %s.", LogInstance().LogLevelsString(), LogInstance().LogLevelToStr(BCLog::DEFAULT_LOG_LEVEL), LogInstance().LogCategoriesString()), ArgsManager::DISALLOW_NEGATION | ArgsManager::DISALLOW_ELISION | ArgsManager::DEBUG_ONLY, OptionsCategory::DEBUG_TEST); argsman.AddArg("-logtimestamps", strprintf("Prepend debug output with timestamp (default: %u)", DEFAULT_LOGTIMESTAMPS), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); #ifdef HAVE_THREAD_LOCAL argsman.AddArg("-logthreadnames", strprintf("Prepend debug output with name of the originating thread (only available on platforms supporting thread_local) (default: %u)", DEFAULT_LOGTHREADNAMES), ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); @@ -55,6 +57,26 @@ void SetLoggingOptions(const ArgsManager& args) fLogIPs = args.GetBoolArg("-logips", DEFAULT_LOGIPS); } +void SetLoggingLevel(const ArgsManager& args) +{ + if (args.IsArgSet("-loglevel")) { + for (const std::string& level_str : args.GetArgs("-loglevel")) { + if (level_str.find_first_of(':', 3) == std::string::npos) { + // user passed a global log level, i.e. -loglevel=<level> + if (!LogInstance().SetLogLevel(level_str)) { + InitWarning(strprintf(_("Unsupported global logging level -loglevel=%s. Valid values: %s."), level_str, LogInstance().LogLevelsString())); + } + } else { + // user passed a category-specific log level, i.e. -loglevel=<category>:<level> + const auto& toks = SplitString(level_str, ':'); + if (!(toks.size() == 2 && LogInstance().SetCategoryLogLevel(toks[0], toks[1]))) { + InitWarning(strprintf(_("Unsupported category-specific logging level -loglevel=%s. Expected -loglevel=<category>:<loglevel>. Valid categories: %s. Valid loglevels: %s."), level_str, LogInstance().LogCategoriesString(), LogInstance().LogLevelsString())); + } + } + } + } +} + void SetLoggingCategories(const ArgsManager& args) { if (args.IsArgSet("-debug")) { diff --git a/src/init/common.h b/src/init/common.h index 2c7f485908..53c860c297 100644 --- a/src/init/common.h +++ b/src/init/common.h @@ -14,6 +14,7 @@ namespace init { void AddLoggingArgs(ArgsManager& args); void SetLoggingOptions(const ArgsManager& args); void SetLoggingCategories(const ArgsManager& args); +void SetLoggingLevel(const ArgsManager& args); bool StartLogging(const ArgsManager& args); void LogPackageVersion(); } // namespace init diff --git a/src/logging.cpp b/src/logging.cpp index 92fc31917f..a3f1d39be5 100644 --- a/src/logging.cpp +++ b/src/logging.cpp @@ -5,15 +5,17 @@ #include <fs.h> #include <logging.h> -#include <util/threadnames.h> #include <util/string.h> +#include <util/threadnames.h> #include <util/time.h> #include <algorithm> #include <array> #include <mutex> +#include <optional> const char * const DEFAULT_DEBUGLOGFILE = "debug.log"; +constexpr auto MAX_USER_SETABLE_SEVERITY_LEVEL{BCLog::Level::Info}; BCLog::Logger& LogInstance() { @@ -122,6 +124,19 @@ bool BCLog::Logger::WillLogCategory(BCLog::LogFlags category) const return (m_categories.load(std::memory_order_relaxed) & category) != 0; } +bool BCLog::Logger::WillLogCategoryLevel(BCLog::LogFlags category, BCLog::Level level) const +{ + // Log messages at Warning and Error level unconditionally, so that + // important troubleshooting information doesn't get lost. + if (level >= BCLog::Level::Warning) return true; + + if (!WillLogCategory(category)) return false; + + StdLockGuard scoped_lock(m_cs); + const auto it{m_category_log_levels.find(category)}; + return level >= (it == m_category_log_levels.end() ? LogLevel() : it->second); +} + bool BCLog::Logger::DefaultShrinkDebugFile() const { return m_categories == BCLog::NONE; @@ -135,7 +150,7 @@ struct CLogCategoryDesc { const CLogCategoryDesc LogCategories[] = { {BCLog::NONE, "0"}, - {BCLog::NONE, "none"}, + {BCLog::NONE, ""}, {BCLog::NET, "net"}, {BCLog::TOR, "tor"}, {BCLog::MEMPOOL, "mempool"}, @@ -165,7 +180,6 @@ const CLogCategoryDesc LogCategories[] = #endif {BCLog::UTIL, "util"}, {BCLog::BLOCKSTORE, "blockstorage"}, - {BCLog::HEADERSSYNC, "headerssync"}, {BCLog::ALL, "1"}, {BCLog::ALL, "all"}, }; @@ -185,11 +199,11 @@ bool GetLogCategory(BCLog::LogFlags& flag, const std::string& str) return false; } -std::string LogLevelToStr(BCLog::Level level) +std::string BCLog::Logger::LogLevelToStr(BCLog::Level level) const { switch (level) { - case BCLog::Level::None: - return "none"; + case BCLog::Level::Trace: + return "trace"; case BCLog::Level::Debug: return "debug"; case BCLog::Level::Info: @@ -198,6 +212,8 @@ std::string LogLevelToStr(BCLog::Level level) return "warning"; case BCLog::Level::Error: return "error"; + case BCLog::Level::None: + return ""; } assert(false); } @@ -207,7 +223,7 @@ std::string LogCategoryToStr(BCLog::LogFlags category) // Each log category string representation should sync with LogCategories switch (category) { case BCLog::LogFlags::NONE: - return "none"; + return ""; case BCLog::LogFlags::NET: return "net"; case BCLog::LogFlags::TOR: @@ -264,14 +280,31 @@ std::string LogCategoryToStr(BCLog::LogFlags category) return "util"; case BCLog::LogFlags::BLOCKSTORE: return "blockstorage"; - case BCLog::LogFlags::HEADERSSYNC: - return "headerssync"; case BCLog::LogFlags::ALL: return "all"; } assert(false); } +static std::optional<BCLog::Level> GetLogLevel(const std::string& level_str) +{ + if (level_str == "trace") { + return BCLog::Level::Trace; + } else if (level_str == "debug") { + return BCLog::Level::Debug; + } else if (level_str == "info") { + return BCLog::Level::Info; + } else if (level_str == "warning") { + return BCLog::Level::Warning; + } else if (level_str == "error") { + return BCLog::Level::Error; + } else if (level_str == "none") { + return BCLog::Level::None; + } else { + return std::nullopt; + } +} + std::vector<LogCategory> BCLog::Logger::LogCategoriesList() const { // Sort log categories by alphabetical order. @@ -290,6 +323,18 @@ std::vector<LogCategory> BCLog::Logger::LogCategoriesList() const return ret; } +/** Log severity levels that can be selected by the user. */ +static constexpr std::array<BCLog::Level, 3> LogLevelsList() +{ + return {BCLog::Level::Info, BCLog::Level::Debug, BCLog::Level::Trace}; +} + +std::string BCLog::Logger::LogLevelsString() const +{ + const auto& levels = LogLevelsList(); + return Join(std::vector<BCLog::Level>{levels.begin(), levels.end()}, ", ", [this](BCLog::Level level) { return LogLevelToStr(level); }); +} + std::string BCLog::Logger::LogTimestampStr(const std::string& str) { std::string strStamped; @@ -337,7 +382,7 @@ namespace BCLog { } } // namespace BCLog -void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, const int source_line, const BCLog::LogFlags category, const BCLog::Level level) +void BCLog::Logger::LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level) { StdLockGuard scoped_lock(m_cs); std::string str_prefixed = LogEscapeMessage(str); @@ -446,3 +491,24 @@ void BCLog::Logger::ShrinkDebugFile() else if (file != nullptr) fclose(file); } + +bool BCLog::Logger::SetLogLevel(const std::string& level_str) +{ + const auto level = GetLogLevel(level_str); + if (!level.has_value() || level.value() > MAX_USER_SETABLE_SEVERITY_LEVEL) return false; + m_log_level = level.value(); + return true; +} + +bool BCLog::Logger::SetCategoryLogLevel(const std::string& category_str, const std::string& level_str) +{ + BCLog::LogFlags flag; + if (!GetLogCategory(flag, category_str)) return false; + + const auto level = GetLogLevel(level_str); + if (!level.has_value() || level.value() > MAX_USER_SETABLE_SEVERITY_LEVEL) return false; + + StdLockGuard scoped_lock(m_cs); + m_category_log_levels[flag] = level.value(); + return true; +} diff --git a/src/logging.h b/src/logging.h index a7f18f7560..fe91ee43a5 100644 --- a/src/logging.h +++ b/src/logging.h @@ -7,8 +7,8 @@ #define BITCOIN_LOGGING_H #include <fs.h> -#include <tinyformat.h> #include <threadsafety.h> +#include <tinyformat.h> #include <util/string.h> #include <atomic> @@ -17,6 +17,7 @@ #include <list> #include <mutex> #include <string> +#include <unordered_map> #include <vector> static const bool DEFAULT_LOGTIMEMICROS = false; @@ -65,16 +66,17 @@ namespace BCLog { #endif UTIL = (1 << 25), BLOCKSTORE = (1 << 26), - HEADERSSYNC = (1 << 27), ALL = ~(uint32_t)0, }; enum class Level { - Debug = 0, - None = 1, - Info = 2, - Warning = 3, - Error = 4, + Trace = 0, // High-volume or detailed logging for development/debugging + Debug, // Reasonably noisy logging, but still usable in production + Info, // Default + Warning, + Error, + None, // Internal use only }; + constexpr auto DEFAULT_LOG_LEVEL{Level::Debug}; class Logger { @@ -92,6 +94,13 @@ namespace BCLog { */ std::atomic_bool m_started_new_line{true}; + //! Category-specific log level. Overrides `m_log_level`. + std::unordered_map<LogFlags, Level> m_category_log_levels GUARDED_BY(m_cs); + + //! If there is no category-specific log level, all logs with a severity + //! level lower than `m_log_level` will be ignored. + std::atomic<Level> m_log_level{DEFAULT_LOG_LEVEL}; + /** Log categories bitfield. */ std::atomic<uint32_t> m_categories{0}; @@ -113,7 +122,7 @@ namespace BCLog { std::atomic<bool> m_reopen_file{false}; /** Send a string to the log output */ - void LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, const int source_line, const BCLog::LogFlags category, const BCLog::Level level); + void LogPrintStr(const std::string& str, const std::string& logging_function, const std::string& source_file, int source_line, BCLog::LogFlags category, BCLog::Level level); /** Returns whether logs will be written to any output */ bool Enabled() const @@ -144,6 +153,22 @@ namespace BCLog { void ShrinkDebugFile(); + std::unordered_map<LogFlags, Level> CategoryLevels() const + { + StdLockGuard scoped_lock(m_cs); + return m_category_log_levels; + } + void SetCategoryLogLevel(const std::unordered_map<LogFlags, Level>& levels) + { + StdLockGuard scoped_lock(m_cs); + m_category_log_levels = levels; + } + bool SetCategoryLogLevel(const std::string& category_str, const std::string& level_str); + + Level LogLevel() const { return m_log_level.load(); } + void SetLogLevel(Level level) { m_log_level = level; } + bool SetLogLevel(const std::string& level); + uint32_t GetCategoryMask() const { return m_categories.load(); } void EnableCategory(LogFlags flag); @@ -152,6 +177,8 @@ namespace BCLog { bool DisableCategory(const std::string& str); bool WillLogCategory(LogFlags category) const; + bool WillLogCategoryLevel(LogFlags category, Level level) const; + /** Returns a vector of the log categories in alphabetical order. */ std::vector<LogCategory> LogCategoriesList() const; /** Returns a string with the log categories in alphabetical order. */ @@ -160,6 +187,12 @@ namespace BCLog { return Join(LogCategoriesList(), ", ", [&](const LogCategory& i) { return i.category; }); }; + //! Returns a string with all user-selectable log levels. + std::string LogLevelsString() const; + + //! Returns the string representation of a log level. + std::string LogLevelToStr(BCLog::Level level) const; + bool DefaultShrinkDebugFile() const; }; @@ -170,12 +203,7 @@ BCLog::Logger& LogInstance(); /** Return true if log accepts specified category, at the specified level. */ static inline bool LogAcceptCategory(BCLog::LogFlags category, BCLog::Level level) { - // Log messages at Warning and Error level unconditionally, so that - // important troubleshooting information doesn't get lost. - if (level >= BCLog::Level::Warning) { - return true; - } - return LogInstance().WillLogCategory(category); + return LogInstance().WillLogCategoryLevel(category, level); } /** Return true if str parses as a log category and set the flag */ diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 746e3bedde..74700580ad 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2820,6 +2820,13 @@ void PeerManagerImpl::ProcessHeadersMessage(CNode& pfrom, Peer& peer, } } + // If our peer has NetPermissionFlags::NoBan privileges, then bypass our + // anti-DoS logic (this saves bandwidth when we connect to a trusted peer + // on startup). + if (pfrom.HasPermission(NetPermissionFlags::NoBan)) { + already_validated_work = true; + } + // At this point, the headers connect to something in our block index. // Do anti-DoS checks to determine if we should process or store for later // processing. diff --git a/src/node/chainstate.cpp b/src/node/chainstate.cpp index ad9293f172..c4dd9ba6c5 100644 --- a/src/node/chainstate.cpp +++ b/src/node/chainstate.cpp @@ -32,6 +32,21 @@ ChainstateLoadResult LoadChainstate(ChainstateManager& chainman, const CacheSize return options.reindex || options.reindex_chainstate || chainstate->CoinsTip().GetBestBlock().IsNull(); }; + if (!hashAssumeValid.IsNull()) { + LogPrintf("Assuming ancestors of block %s have valid signatures.\n", hashAssumeValid.GetHex()); + } else { + LogPrintf("Validating signatures for all blocks.\n"); + } + LogPrintf("Setting nMinimumChainWork=%s\n", nMinimumChainWork.GetHex()); + if (nMinimumChainWork < UintToArith256(chainman.GetConsensus().nMinimumChainWork)) { + LogPrintf("Warning: nMinimumChainWork set below default value of %s\n", chainman.GetConsensus().nMinimumChainWork.GetHex()); + } + if (nPruneTarget == std::numeric_limits<uint64_t>::max()) { + LogPrintf("Block pruning enabled. Use RPC call pruneblockchain(height) to manually prune block and undo files.\n"); + } else if (nPruneTarget) { + LogPrintf("Prune configured to target %u MiB on disk for block and undo files.\n", nPruneTarget / 1024 / 1024); + } + LOCK(cs_main); chainman.InitializeChainstate(options.mempool); chainman.m_total_coinstip_cache = cache_sizes.coins; diff --git a/src/node/mempool_args.cpp b/src/node/mempool_args.cpp index cb2466804a..8c929e5e0d 100644 --- a/src/node/mempool_args.cpp +++ b/src/node/mempool_args.cpp @@ -12,6 +12,7 @@ #include <logging.h> #include <policy/feerate.h> #include <policy/policy.h> +#include <script/standard.h> #include <tinyformat.h> #include <util/error.h> #include <util/moneystr.h> diff --git a/src/primitives/block.h b/src/primitives/block.h index 76aba6c899..2e26e6c426 100644 --- a/src/primitives/block.h +++ b/src/primitives/block.h @@ -123,7 +123,7 @@ struct CBlockLocator CBlockLocator() {} - explicit CBlockLocator(const std::vector<uint256>& vHaveIn) : vHave(vHaveIn) {} + explicit CBlockLocator(std::vector<uint256>&& have) : vHave(std::move(have)) {} SERIALIZE_METHODS(CBlockLocator, obj) { diff --git a/src/qt/bitcoinstrings.cpp b/src/qt/bitcoinstrings.cpp index 13694c638d..4489c00932 100644 --- a/src/qt/bitcoinstrings.cpp +++ b/src/qt/bitcoinstrings.cpp @@ -277,6 +277,7 @@ QT_TRANSLATE_NOOP("bitcoin-core", "Unable to allocate memory for -maxsigcachesiz QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer (bind returned error %s)"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to bind to %s on this computer. %s is probably already running."), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to create the PID file '%s': %s"), +QT_TRANSLATE_NOOP("bitcoin-core", "Unable to find UTXO for external input"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to generate initial keys"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to generate keys"), QT_TRANSLATE_NOOP("bitcoin-core", "Unable to open %s for writing"), diff --git a/src/qt/locale/bitcoin_en.ts b/src/qt/locale/bitcoin_en.ts index 0fe69051a4..883d3fe24a 100644 --- a/src/qt/locale/bitcoin_en.ts +++ b/src/qt/locale/bitcoin_en.ts @@ -313,7 +313,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <context> <name>BitcoinApplication</name> <message> - <location filename="../bitcoin.cpp" line="+286"/> + <location filename="../bitcoin.cpp" line="+288"/> <source>Settings file %1 might be corrupt or invalid.</source> <translation type="unfinished"></translation> </message> @@ -417,12 +417,12 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+429"/> + <location line="+439"/> <source>Proxy is <b>enabled</b>: %1</source> <translation type="unfinished"></translation> </message> <message> - <location line="-1150"/> + <location line="-1160"/> <source>Send coins to a Bitcoin address</source> <translation>Send coins to a Bitcoin address</translation> </message> @@ -542,7 +542,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+48"/> + <location line="+58"/> <source>Synchronizing with network…</source> <translation type="unfinished"></translation> </message> @@ -567,7 +567,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation type="unfinished"></translation> </message> <message> - <location line="-823"/> + <location line="-833"/> <source>Request payments (generates QR codes and bitcoin: URIs)</source> <translation type="unfinished"></translation> </message> @@ -587,7 +587,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation type="unfinished"></translation> </message> <message numerus="yes"> - <location line="+739"/> + <location line="+749"/> <source>Processed %n block(s) of transaction history.</source> <translation> <numerusform>Processed %n block of transaction history.</numerusform> @@ -635,7 +635,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation>Up to date</translation> </message> <message> - <location line="-808"/> + <location line="-818"/> <source>Ctrl+Q</source> <translation type="unfinished"></translation> </message> @@ -829,7 +829,12 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+159"/> + <location line="+17"/> + <source>Pre-syncing Headers (%1%)…</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+152"/> <source>Error: %1</source> <translation type="unfinished"></translation> </message> @@ -1513,7 +1518,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <message> <location line="+7"/> <location line="+26"/> - <location filename="../modaloverlay.cpp" line="+152"/> + <location filename="../modaloverlay.cpp" line="+155"/> <source>Unknown…</source> <translation type="unfinished"></translation> </message> @@ -1554,15 +1559,20 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../modaloverlay.cpp" line="-118"/> + <location filename="../modaloverlay.cpp" line="-121"/> <source>%1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain.</source> <translation type="unfinished"></translation> </message> <message> - <location line="+124"/> + <location line="+127"/> <source>Unknown. Syncing Headers (%1, %2%)…</source> <translation type="unfinished"></translation> </message> + <message> + <location line="+5"/> + <source>Unknown. Pre-syncing Headers (%1, %2%)…</source> + <translation type="unfinished"></translation> + </message> </context> <context> <name>OpenURIDialog</name> @@ -2181,7 +2191,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <translation type="unfinished"></translation> </message> <message> - <location filename="../overviewpage.cpp" line="+186"/> + <location filename="../overviewpage.cpp" line="+185"/> <source>Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings->Mask values.</source> <translation type="unfinished"></translation> </message> @@ -2685,7 +2695,7 @@ If you are receiving this error you should request the merchant provide a BIP21 <translation type="unfinished"></translation> </message> <message> - <location filename="../modaloverlay.cpp" line="-35"/> + <location filename="../modaloverlay.cpp" line="-40"/> <source>unknown</source> <translation type="unfinished"></translation> </message> @@ -3623,7 +3633,7 @@ For more information on using this console, type %6. <name>SendCoinsDialog</name> <message> <location filename="../forms/sendcoinsdialog.ui" line="+14"/> - <location filename="../sendcoinsdialog.cpp" line="+759"/> + <location filename="../sendcoinsdialog.cpp" line="+757"/> <source>Send Coins</source> <translation>Send Coins</translation> </message> @@ -3810,7 +3820,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 <translation>S&end</translation> </message> <message> - <location filename="../sendcoinsdialog.cpp" line="-660"/> + <location filename="../sendcoinsdialog.cpp" line="-658"/> <source>Copy quantity</source> <translation type="unfinished"></translation> </message> @@ -3845,7 +3855,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 <translation type="unfinished"></translation> </message> <message> - <location line="+76"/> + <location line="+74"/> <source>%1 (%2 blocks)</source> <translation type="unfinished"></translation> </message> @@ -5042,7 +5052,7 @@ Go to File > Open Wallet to load a wallet. <context> <name>WalletModel</name> <message> - <location filename="../walletmodel.cpp" line="+221"/> + <location filename="../walletmodel.cpp" line="+232"/> <source>Send Coins</source> <translation type="unfinished">Send Coins</translation> </message> @@ -5954,6 +5964,11 @@ Go to File > Open Wallet to load a wallet. </message> <message> <location line="+1"/> + <source>Unable to find UTXO for external input</source> + <translation type="unfinished"></translation> + </message> + <message> + <location line="+1"/> <source>Unable to generate initial keys</source> <translation type="unfinished"></translation> </message> diff --git a/src/qt/locale/bitcoin_en.xlf b/src/qt/locale/bitcoin_en.xlf index c5f0c933f4..7b2cfd30cf 100644 --- a/src/qt/locale/bitcoin_en.xlf +++ b/src/qt/locale/bitcoin_en.xlf @@ -268,61 +268,61 @@ Signing is only possible with addresses of the type 'legacy'.</source> <group restype="x-trolltech-linguist-context" resname="BitcoinApplication"> <trans-unit id="_msg58"> <source xml:space="preserve">Settings file %1 might be corrupt or invalid.</source> - <context-group purpose="location"><context context-type="linenumber">286</context></context-group> + <context-group purpose="location"><context context-type="linenumber">288</context></context-group> </trans-unit> <trans-unit id="_msg59"> <source xml:space="preserve">Runaway exception</source> - <context-group purpose="location"><context context-type="linenumber">464</context></context-group> + <context-group purpose="location"><context context-type="linenumber">466</context></context-group> </trans-unit> <trans-unit id="_msg60"> <source xml:space="preserve">A fatal error occurred. %1 can no longer continue safely and will quit.</source> - <context-group purpose="location"><context context-type="linenumber">465</context></context-group> + <context-group purpose="location"><context context-type="linenumber">467</context></context-group> </trans-unit> <trans-unit id="_msg61"> <source xml:space="preserve">Internal error</source> - <context-group purpose="location"><context context-type="linenumber">474</context></context-group> + <context-group purpose="location"><context context-type="linenumber">476</context></context-group> </trans-unit> <trans-unit id="_msg62"> <source xml:space="preserve">An internal error occurred. %1 will attempt to continue safely. This is an unexpected bug which can be reported as described below.</source> - <context-group purpose="location"><context context-type="linenumber">475</context></context-group> + <context-group purpose="location"><context context-type="linenumber">477</context></context-group> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="QObject"> <trans-unit id="_msg63"> <source xml:space="preserve">Do you want to reset settings to default values, or to abort without making changes?</source> - <context-group purpose="location"><context context-type="linenumber">181</context></context-group> + <context-group purpose="location"><context context-type="linenumber">183</context></context-group> <note annotates="source" from="developer">Explanatory text shown on startup when the settings file cannot be read. Prompts user to make a choice between resetting or aborting.</note> </trans-unit> <trans-unit id="_msg64"> <source xml:space="preserve">A fatal error occurred. Check that settings file is writable, or try running with -nosettings.</source> - <context-group purpose="location"><context context-type="linenumber">205</context></context-group> + <context-group purpose="location"><context context-type="linenumber">207</context></context-group> <note annotates="source" from="developer">Explanatory text shown on startup when the settings file could not be written. Prompts user to check that we have the ability to write to the file. Explains that the user has the option of running without a settings file.</note> </trans-unit> <trans-unit id="_msg65"> <source xml:space="preserve">Error: Specified data directory "%1" does not exist.</source> - <context-group purpose="location"><context context-type="linenumber">598</context></context-group> + <context-group purpose="location"><context context-type="linenumber">600</context></context-group> </trans-unit> <trans-unit id="_msg66"> <source xml:space="preserve">Error: Cannot parse configuration file: %1.</source> - <context-group purpose="location"><context context-type="linenumber">604</context></context-group> + <context-group purpose="location"><context context-type="linenumber">606</context></context-group> </trans-unit> <trans-unit id="_msg67"> <source xml:space="preserve">Error: %1</source> - <context-group purpose="location"><context context-type="linenumber">619</context></context-group> + <context-group purpose="location"><context context-type="linenumber">621</context></context-group> </trans-unit> <trans-unit id="_msg68"> <source xml:space="preserve">%1 didn't yet exit safely…</source> - <context-group purpose="location"><context context-type="linenumber">693</context></context-group> + <context-group purpose="location"><context context-type="linenumber">695</context></context-group> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="bitcoin-core"> <trans-unit id="_msg69"> <source xml:space="preserve">Settings file could not be read</source> - <context-group purpose="location"><context context-type="linenumber">174</context></context-group> + <context-group purpose="location"><context context-type="linenumber">176</context></context-group> </trans-unit> <trans-unit id="_msg70"> <source xml:space="preserve">Settings file could not be written</source> - <context-group purpose="location"><context context-type="linenumber">197</context></context-group> + <context-group purpose="location"><context context-type="linenumber">199</context></context-group> </trans-unit> </group> </body></file> @@ -391,7 +391,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> </trans-unit> <trans-unit id="_msg86"> <source xml:space="preserve">Proxy is <b>enabled</b>: %1</source> - <context-group purpose="location"><context context-type="linenumber">1411</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1421</context></context-group> </trans-unit> <trans-unit id="_msg87"> <source xml:space="preserve">Send coins to a Bitcoin address</source> @@ -491,23 +491,23 @@ Signing is only possible with addresses of the type 'legacy'.</source> </trans-unit> <trans-unit id="_msg111"> <source xml:space="preserve">Synchronizing with network…</source> - <context-group purpose="location"><context context-type="linenumber">1074</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1084</context></context-group> </trans-unit> <trans-unit id="_msg112"> <source xml:space="preserve">Indexing blocks on disk…</source> - <context-group purpose="location"><context context-type="linenumber">1079</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1089</context></context-group> </trans-unit> <trans-unit id="_msg113"> <source xml:space="preserve">Processing blocks on disk…</source> - <context-group purpose="location"><context context-type="linenumber">1081</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1091</context></context-group> </trans-unit> <trans-unit id="_msg114"> <source xml:space="preserve">Reindexing blocks on disk…</source> - <context-group purpose="location"><context context-type="linenumber">1085</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1095</context></context-group> </trans-unit> <trans-unit id="_msg115"> <source xml:space="preserve">Connecting to peers…</source> - <context-group purpose="location"><context context-type="linenumber">1091</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1101</context></context-group> </trans-unit> <trans-unit id="_msg116"> <source xml:space="preserve">Request payments (generates QR codes and bitcoin: URIs)</source> @@ -526,7 +526,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> <context-group purpose="location"><context context-type="linenumber">361</context></context-group> </trans-unit> <group restype="x-gettext-plurals"> - <context-group purpose="location"><context context-type="linenumber">1100</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1110</context></context-group> <trans-unit id="_msg120[0]"> <source xml:space="preserve">Processed %n block(s) of transaction history.</source> </trans-unit> @@ -536,35 +536,35 @@ Signing is only possible with addresses of the type 'legacy'.</source> </group> <trans-unit id="_msg121"> <source xml:space="preserve">%1 behind</source> - <context-group purpose="location"><context context-type="linenumber">1123</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1133</context></context-group> </trans-unit> <trans-unit id="_msg122"> <source xml:space="preserve">Catching up…</source> - <context-group purpose="location"><context context-type="linenumber">1128</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1138</context></context-group> </trans-unit> <trans-unit id="_msg123"> <source xml:space="preserve">Last received block was generated %1 ago.</source> - <context-group purpose="location"><context context-type="linenumber">1147</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1157</context></context-group> </trans-unit> <trans-unit id="_msg124"> <source xml:space="preserve">Transactions after this will not yet be visible.</source> - <context-group purpose="location"><context context-type="linenumber">1149</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1159</context></context-group> </trans-unit> <trans-unit id="_msg125"> <source xml:space="preserve">Error</source> - <context-group purpose="location"><context context-type="linenumber">1174</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1184</context></context-group> </trans-unit> <trans-unit id="_msg126"> <source xml:space="preserve">Warning</source> - <context-group purpose="location"><context context-type="linenumber">1178</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1188</context></context-group> </trans-unit> <trans-unit id="_msg127"> <source xml:space="preserve">Information</source> - <context-group purpose="location"><context context-type="linenumber">1182</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1192</context></context-group> </trans-unit> <trans-unit id="_msg128"> <source xml:space="preserve">Up to date</source> - <context-group purpose="location"><context context-type="linenumber">1104</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1114</context></context-group> </trans-unit> <trans-unit id="_msg129"> <source xml:space="preserve">Ctrl+Q</source> @@ -727,150 +727,154 @@ Signing is only possible with addresses of the type 'legacy'.</source> <note annotates="source" from="developer">A context menu item. The network activity was disabled previously.</note> </trans-unit> <trans-unit id="_msg165"> - <source xml:space="preserve">Error: %1</source> - <context-group purpose="location"><context context-type="linenumber">1175</context></context-group> + <source xml:space="preserve">Pre-syncing Headers (%1%)…</source> + <context-group purpose="location"><context context-type="linenumber">1033</context></context-group> </trans-unit> <trans-unit id="_msg166"> - <source xml:space="preserve">Warning: %1</source> - <context-group purpose="location"><context context-type="linenumber">1179</context></context-group> + <source xml:space="preserve">Error: %1</source> + <context-group purpose="location"><context context-type="linenumber">1185</context></context-group> </trans-unit> <trans-unit id="_msg167"> + <source xml:space="preserve">Warning: %1</source> + <context-group purpose="location"><context context-type="linenumber">1189</context></context-group> + </trans-unit> + <trans-unit id="_msg168"> <source xml:space="preserve">Date: %1 </source> - <context-group purpose="location"><context context-type="linenumber">1287</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1297</context></context-group> </trans-unit> - <trans-unit id="_msg168"> + <trans-unit id="_msg169"> <source xml:space="preserve">Amount: %1 </source> - <context-group purpose="location"><context context-type="linenumber">1288</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1298</context></context-group> </trans-unit> - <trans-unit id="_msg169"> + <trans-unit id="_msg170"> <source xml:space="preserve">Wallet: %1 </source> - <context-group purpose="location"><context context-type="linenumber">1290</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1300</context></context-group> </trans-unit> - <trans-unit id="_msg170"> + <trans-unit id="_msg171"> <source xml:space="preserve">Type: %1 </source> - <context-group purpose="location"><context context-type="linenumber">1292</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1302</context></context-group> </trans-unit> - <trans-unit id="_msg171"> + <trans-unit id="_msg172"> <source xml:space="preserve">Label: %1 </source> - <context-group purpose="location"><context context-type="linenumber">1294</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1304</context></context-group> </trans-unit> - <trans-unit id="_msg172"> + <trans-unit id="_msg173"> <source xml:space="preserve">Address: %1 </source> - <context-group purpose="location"><context context-type="linenumber">1296</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1306</context></context-group> </trans-unit> - <trans-unit id="_msg173"> + <trans-unit id="_msg174"> <source xml:space="preserve">Sent transaction</source> - <context-group purpose="location"><context context-type="linenumber">1297</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1307</context></context-group> </trans-unit> - <trans-unit id="_msg174"> + <trans-unit id="_msg175"> <source xml:space="preserve">Incoming transaction</source> - <context-group purpose="location"><context context-type="linenumber">1297</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1307</context></context-group> </trans-unit> - <trans-unit id="_msg175"> + <trans-unit id="_msg176"> <source xml:space="preserve">HD key generation is <b>enabled</b></source> - <context-group purpose="location"><context context-type="linenumber">1349</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1359</context></context-group> </trans-unit> - <trans-unit id="_msg176"> + <trans-unit id="_msg177"> <source xml:space="preserve">HD key generation is <b>disabled</b></source> - <context-group purpose="location"><context context-type="linenumber">1349</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1359</context></context-group> </trans-unit> - <trans-unit id="_msg177"> + <trans-unit id="_msg178"> <source xml:space="preserve">Private key <b>disabled</b></source> - <context-group purpose="location"><context context-type="linenumber">1349</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1359</context></context-group> </trans-unit> - <trans-unit id="_msg178"> + <trans-unit id="_msg179"> <source xml:space="preserve">Wallet is <b>encrypted</b> and currently <b>unlocked</b></source> - <context-group purpose="location"><context context-type="linenumber">1372</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1382</context></context-group> </trans-unit> - <trans-unit id="_msg179"> + <trans-unit id="_msg180"> <source xml:space="preserve">Wallet is <b>encrypted</b> and currently <b>locked</b></source> - <context-group purpose="location"><context context-type="linenumber">1380</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1390</context></context-group> </trans-unit> - <trans-unit id="_msg180"> + <trans-unit id="_msg181"> <source xml:space="preserve">Original message:</source> - <context-group purpose="location"><context context-type="linenumber">1499</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1509</context></context-group> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="UnitDisplayStatusBarControl"> - <trans-unit id="_msg181"> + <trans-unit id="_msg182"> <source xml:space="preserve">Unit to show amounts in. Click to select another unit.</source> - <context-group purpose="location"><context context-type="linenumber">1540</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1550</context></context-group> </trans-unit> </group> </body></file> <file original="../forms/coincontroldialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="CoinControlDialog"> - <trans-unit id="_msg182"> + <trans-unit id="_msg183"> <source xml:space="preserve">Coin Selection</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg183"> + <trans-unit id="_msg184"> <source xml:space="preserve">Quantity:</source> <context-group purpose="location"><context context-type="linenumber">48</context></context-group> </trans-unit> - <trans-unit id="_msg184"> + <trans-unit id="_msg185"> <source xml:space="preserve">Bytes:</source> <context-group purpose="location"><context context-type="linenumber">77</context></context-group> </trans-unit> - <trans-unit id="_msg185"> + <trans-unit id="_msg186"> <source xml:space="preserve">Amount:</source> <context-group purpose="location"><context context-type="linenumber">122</context></context-group> </trans-unit> - <trans-unit id="_msg186"> + <trans-unit id="_msg187"> <source xml:space="preserve">Fee:</source> <context-group purpose="location"><context context-type="linenumber">202</context></context-group> </trans-unit> - <trans-unit id="_msg187"> + <trans-unit id="_msg188"> <source xml:space="preserve">Dust:</source> <context-group purpose="location"><context context-type="linenumber">154</context></context-group> </trans-unit> - <trans-unit id="_msg188"> + <trans-unit id="_msg189"> <source xml:space="preserve">After Fee:</source> <context-group purpose="location"><context context-type="linenumber">247</context></context-group> </trans-unit> - <trans-unit id="_msg189"> + <trans-unit id="_msg190"> <source xml:space="preserve">Change:</source> <context-group purpose="location"><context context-type="linenumber">279</context></context-group> </trans-unit> - <trans-unit id="_msg190"> + <trans-unit id="_msg191"> <source xml:space="preserve">(un)select all</source> <context-group purpose="location"><context context-type="linenumber">335</context></context-group> </trans-unit> - <trans-unit id="_msg191"> + <trans-unit id="_msg192"> <source xml:space="preserve">Tree mode</source> <context-group purpose="location"><context context-type="linenumber">351</context></context-group> </trans-unit> - <trans-unit id="_msg192"> + <trans-unit id="_msg193"> <source xml:space="preserve">List mode</source> <context-group purpose="location"><context context-type="linenumber">364</context></context-group> </trans-unit> - <trans-unit id="_msg193"> + <trans-unit id="_msg194"> <source xml:space="preserve">Amount</source> <context-group purpose="location"><context context-type="linenumber">420</context></context-group> </trans-unit> - <trans-unit id="_msg194"> + <trans-unit id="_msg195"> <source xml:space="preserve">Received with label</source> <context-group purpose="location"><context context-type="linenumber">425</context></context-group> </trans-unit> - <trans-unit id="_msg195"> + <trans-unit id="_msg196"> <source xml:space="preserve">Received with address</source> <context-group purpose="location"><context context-type="linenumber">430</context></context-group> </trans-unit> - <trans-unit id="_msg196"> + <trans-unit id="_msg197"> <source xml:space="preserve">Date</source> <context-group purpose="location"><context context-type="linenumber">435</context></context-group> </trans-unit> - <trans-unit id="_msg197"> + <trans-unit id="_msg198"> <source xml:space="preserve">Confirmations</source> <context-group purpose="location"><context context-type="linenumber">440</context></context-group> </trans-unit> - <trans-unit id="_msg198"> + <trans-unit id="_msg199"> <source xml:space="preserve">Confirmed</source> <context-group purpose="location"><context context-type="linenumber">443</context></context-group> </trans-unit> @@ -878,88 +882,88 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../coincontroldialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="CoinControlDialog"> - <trans-unit id="_msg199"> + <trans-unit id="_msg200"> <source xml:space="preserve">Copy amount</source> <context-group purpose="location"><context context-type="linenumber">69</context></context-group> </trans-unit> - <trans-unit id="_msg200"> + <trans-unit id="_msg201"> <source xml:space="preserve">&Copy address</source> <context-group purpose="location"><context context-type="linenumber">58</context></context-group> </trans-unit> - <trans-unit id="_msg201"> + <trans-unit id="_msg202"> <source xml:space="preserve">Copy &label</source> <context-group purpose="location"><context context-type="linenumber">59</context></context-group> </trans-unit> - <trans-unit id="_msg202"> + <trans-unit id="_msg203"> <source xml:space="preserve">Copy &amount</source> <context-group purpose="location"><context context-type="linenumber">60</context></context-group> </trans-unit> - <trans-unit id="_msg203"> + <trans-unit id="_msg204"> <source xml:space="preserve">Copy transaction &ID and output index</source> <context-group purpose="location"><context context-type="linenumber">61</context></context-group> </trans-unit> - <trans-unit id="_msg204"> + <trans-unit id="_msg205"> <source xml:space="preserve">L&ock unspent</source> <context-group purpose="location"><context context-type="linenumber">63</context></context-group> </trans-unit> - <trans-unit id="_msg205"> + <trans-unit id="_msg206"> <source xml:space="preserve">&Unlock unspent</source> <context-group purpose="location"><context context-type="linenumber">64</context></context-group> </trans-unit> - <trans-unit id="_msg206"> + <trans-unit id="_msg207"> <source xml:space="preserve">Copy quantity</source> <context-group purpose="location"><context context-type="linenumber">68</context></context-group> </trans-unit> - <trans-unit id="_msg207"> + <trans-unit id="_msg208"> <source xml:space="preserve">Copy fee</source> <context-group purpose="location"><context context-type="linenumber">70</context></context-group> </trans-unit> - <trans-unit id="_msg208"> + <trans-unit id="_msg209"> <source xml:space="preserve">Copy after fee</source> <context-group purpose="location"><context context-type="linenumber">71</context></context-group> </trans-unit> - <trans-unit id="_msg209"> + <trans-unit id="_msg210"> <source xml:space="preserve">Copy bytes</source> <context-group purpose="location"><context context-type="linenumber">72</context></context-group> </trans-unit> - <trans-unit id="_msg210"> + <trans-unit id="_msg211"> <source xml:space="preserve">Copy dust</source> <context-group purpose="location"><context context-type="linenumber">73</context></context-group> </trans-unit> - <trans-unit id="_msg211"> + <trans-unit id="_msg212"> <source xml:space="preserve">Copy change</source> <context-group purpose="location"><context context-type="linenumber">74</context></context-group> </trans-unit> - <trans-unit id="_msg212"> + <trans-unit id="_msg213"> <source xml:space="preserve">(%1 locked)</source> <context-group purpose="location"><context context-type="linenumber">380</context></context-group> </trans-unit> - <trans-unit id="_msg213"> + <trans-unit id="_msg214"> <source xml:space="preserve">yes</source> <context-group purpose="location"><context context-type="linenumber">534</context></context-group> </trans-unit> - <trans-unit id="_msg214"> + <trans-unit id="_msg215"> <source xml:space="preserve">no</source> <context-group purpose="location"><context context-type="linenumber">534</context></context-group> </trans-unit> - <trans-unit id="_msg215"> + <trans-unit id="_msg216"> <source xml:space="preserve">This label turns red if any recipient receives an amount smaller than the current dust threshold.</source> <context-group purpose="location"><context context-type="linenumber">548</context></context-group> </trans-unit> - <trans-unit id="_msg216"> + <trans-unit id="_msg217"> <source xml:space="preserve">Can vary +/- %1 satoshi(s) per input.</source> <context-group purpose="location"><context context-type="linenumber">553</context></context-group> </trans-unit> - <trans-unit id="_msg217"> + <trans-unit id="_msg218"> <source xml:space="preserve">(no label)</source> <context-group purpose="location"><context context-type="linenumber">600</context></context-group> <context-group purpose="location"><context context-type="linenumber">654</context></context-group> </trans-unit> - <trans-unit id="_msg218"> + <trans-unit id="_msg219"> <source xml:space="preserve">change from %1 (%2)</source> <context-group purpose="location"><context context-type="linenumber">647</context></context-group> </trans-unit> - <trans-unit id="_msg219"> + <trans-unit id="_msg220"> <source xml:space="preserve">(change)</source> <context-group purpose="location"><context context-type="linenumber">648</context></context-group> </trans-unit> @@ -967,114 +971,114 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../walletcontroller.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="CreateWalletActivity"> - <trans-unit id="_msg220"> + <trans-unit id="_msg221"> <source xml:space="preserve">Create Wallet</source> <context-group purpose="location"><context context-type="linenumber">244</context></context-group> <note annotates="source" from="developer">Title of window indicating the progress of creation of a new wallet.</note> </trans-unit> - <trans-unit id="_msg221"> + <trans-unit id="_msg222"> <source xml:space="preserve">Creating Wallet <b>%1</b>…</source> <context-group purpose="location"><context context-type="linenumber">247</context></context-group> <note annotates="source" from="developer">Descriptive text of the create wallet progress window which indicates to the user which wallet is currently being created.</note> </trans-unit> - <trans-unit id="_msg222"> + <trans-unit id="_msg223"> <source xml:space="preserve">Create wallet failed</source> <context-group purpose="location"><context context-type="linenumber">280</context></context-group> </trans-unit> - <trans-unit id="_msg223"> + <trans-unit id="_msg224"> <source xml:space="preserve">Create wallet warning</source> <context-group purpose="location"><context context-type="linenumber">282</context></context-group> </trans-unit> - <trans-unit id="_msg224"> + <trans-unit id="_msg225"> <source xml:space="preserve">Can't list signers</source> <context-group purpose="location"><context context-type="linenumber">298</context></context-group> </trans-unit> - <trans-unit id="_msg225"> + <trans-unit id="_msg226"> <source xml:space="preserve">Too many external signers found</source> <context-group purpose="location"><context context-type="linenumber">301</context></context-group> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="LoadWalletsActivity"> - <trans-unit id="_msg226"> + <trans-unit id="_msg227"> <source xml:space="preserve">Load Wallets</source> <context-group purpose="location"><context context-type="linenumber">375</context></context-group> <note annotates="source" from="developer">Title of progress window which is displayed when wallets are being loaded.</note> </trans-unit> - <trans-unit id="_msg227"> + <trans-unit id="_msg228"> <source xml:space="preserve">Loading wallets…</source> <context-group purpose="location"><context context-type="linenumber">378</context></context-group> <note annotates="source" from="developer">Descriptive text of the load wallets progress window which indicates to the user that wallets are currently being loaded.</note> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="OpenWalletActivity"> - <trans-unit id="_msg228"> + <trans-unit id="_msg229"> <source xml:space="preserve">Open wallet failed</source> <context-group purpose="location"><context context-type="linenumber">332</context></context-group> </trans-unit> - <trans-unit id="_msg229"> + <trans-unit id="_msg230"> <source xml:space="preserve">Open wallet warning</source> <context-group purpose="location"><context context-type="linenumber">334</context></context-group> </trans-unit> - <trans-unit id="_msg230"> + <trans-unit id="_msg231"> <source xml:space="preserve">default wallet</source> <context-group purpose="location"><context context-type="linenumber">344</context></context-group> </trans-unit> - <trans-unit id="_msg231"> + <trans-unit id="_msg232"> <source xml:space="preserve">Open Wallet</source> <context-group purpose="location"><context context-type="linenumber">348</context></context-group> <note annotates="source" from="developer">Title of window indicating the progress of opening of a wallet.</note> </trans-unit> - <trans-unit id="_msg232"> + <trans-unit id="_msg233"> <source xml:space="preserve">Opening Wallet <b>%1</b>…</source> <context-group purpose="location"><context context-type="linenumber">351</context></context-group> <note annotates="source" from="developer">Descriptive text of the open wallet progress window which indicates to the user which wallet is currently being opened.</note> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="RestoreWalletActivity"> - <trans-unit id="_msg233"> + <trans-unit id="_msg234"> <source xml:space="preserve">Restore Wallet</source> <context-group purpose="location"><context context-type="linenumber">400</context></context-group> <note annotates="source" from="developer">Title of progress window which is displayed when wallets are being restored.</note> </trans-unit> - <trans-unit id="_msg234"> + <trans-unit id="_msg235"> <source xml:space="preserve">Restoring Wallet <b>%1</b>…</source> <context-group purpose="location"><context context-type="linenumber">403</context></context-group> <note annotates="source" from="developer">Descriptive text of the restore wallets progress window which indicates to the user that wallets are currently being restored.</note> </trans-unit> - <trans-unit id="_msg235"> + <trans-unit id="_msg236"> <source xml:space="preserve">Restore wallet failed</source> <context-group purpose="location"><context context-type="linenumber">422</context></context-group> <note annotates="source" from="developer">Title of message box which is displayed when the wallet could not be restored.</note> </trans-unit> - <trans-unit id="_msg236"> + <trans-unit id="_msg237"> <source xml:space="preserve">Restore wallet warning</source> <context-group purpose="location"><context context-type="linenumber">425</context></context-group> <note annotates="source" from="developer">Title of message box which is displayed when the wallet is restored with some warning.</note> </trans-unit> - <trans-unit id="_msg237"> + <trans-unit id="_msg238"> <source xml:space="preserve">Restore wallet message</source> <context-group purpose="location"><context context-type="linenumber">428</context></context-group> <note annotates="source" from="developer">Title of message box which is displayed when the wallet is successfully restored.</note> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="WalletController"> - <trans-unit id="_msg238"> + <trans-unit id="_msg239"> <source xml:space="preserve">Close wallet</source> <context-group purpose="location"><context context-type="linenumber">84</context></context-group> </trans-unit> - <trans-unit id="_msg239"> + <trans-unit id="_msg240"> <source xml:space="preserve">Are you sure you wish to close the wallet <i>%1</i>?</source> <context-group purpose="location"><context context-type="linenumber">85</context></context-group> </trans-unit> - <trans-unit id="_msg240"> + <trans-unit id="_msg241"> <source xml:space="preserve">Closing the wallet for too long can result in having to resync the entire chain if pruning is enabled.</source> <context-group purpose="location"><context context-type="linenumber">86</context></context-group> </trans-unit> - <trans-unit id="_msg241"> + <trans-unit id="_msg242"> <source xml:space="preserve">Close all wallets</source> <context-group purpose="location"><context context-type="linenumber">99</context></context-group> </trans-unit> - <trans-unit id="_msg242"> + <trans-unit id="_msg243"> <source xml:space="preserve">Are you sure you wish to close all wallets?</source> <context-group purpose="location"><context context-type="linenumber">100</context></context-group> </trans-unit> @@ -1082,59 +1086,59 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../forms/createwalletdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="CreateWalletDialog"> - <trans-unit id="_msg243"> + <trans-unit id="_msg244"> <source xml:space="preserve">Create Wallet</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg244"> + <trans-unit id="_msg245"> <source xml:space="preserve">Wallet Name</source> <context-group purpose="location"><context context-type="linenumber">25</context></context-group> </trans-unit> - <trans-unit id="_msg245"> + <trans-unit id="_msg246"> <source xml:space="preserve">Wallet</source> <context-group purpose="location"><context context-type="linenumber">38</context></context-group> </trans-unit> - <trans-unit id="_msg246"> + <trans-unit id="_msg247"> <source xml:space="preserve">Encrypt the wallet. The wallet will be encrypted with a passphrase of your choice.</source> <context-group purpose="location"><context context-type="linenumber">47</context></context-group> </trans-unit> - <trans-unit id="_msg247"> + <trans-unit id="_msg248"> <source xml:space="preserve">Encrypt Wallet</source> <context-group purpose="location"><context context-type="linenumber">50</context></context-group> </trans-unit> - <trans-unit id="_msg248"> + <trans-unit id="_msg249"> <source xml:space="preserve">Advanced Options</source> <context-group purpose="location"><context context-type="linenumber">76</context></context-group> </trans-unit> - <trans-unit id="_msg249"> + <trans-unit id="_msg250"> <source xml:space="preserve">Disable private keys for this wallet. Wallets with private keys disabled will have no private keys and cannot have an HD seed or imported private keys. This is ideal for watch-only wallets.</source> <context-group purpose="location"><context context-type="linenumber">85</context></context-group> </trans-unit> - <trans-unit id="_msg250"> + <trans-unit id="_msg251"> <source xml:space="preserve">Disable Private Keys</source> <context-group purpose="location"><context context-type="linenumber">88</context></context-group> </trans-unit> - <trans-unit id="_msg251"> + <trans-unit id="_msg252"> <source xml:space="preserve">Make a blank wallet. Blank wallets do not initially have private keys or scripts. Private keys and addresses can be imported, or an HD seed can be set, at a later time.</source> <context-group purpose="location"><context context-type="linenumber">95</context></context-group> </trans-unit> - <trans-unit id="_msg252"> + <trans-unit id="_msg253"> <source xml:space="preserve">Make Blank Wallet</source> <context-group purpose="location"><context context-type="linenumber">98</context></context-group> </trans-unit> - <trans-unit id="_msg253"> + <trans-unit id="_msg254"> <source xml:space="preserve">Use descriptors for scriptPubKey management</source> <context-group purpose="location"><context context-type="linenumber">105</context></context-group> </trans-unit> - <trans-unit id="_msg254"> + <trans-unit id="_msg255"> <source xml:space="preserve">Descriptor Wallet</source> <context-group purpose="location"><context context-type="linenumber">108</context></context-group> </trans-unit> - <trans-unit id="_msg255"> + <trans-unit id="_msg256"> <source xml:space="preserve">Use an external signing device such as a hardware wallet. Configure the external signer script in wallet preferences first.</source> <context-group purpose="location"><context context-type="linenumber">118</context></context-group> </trans-unit> - <trans-unit id="_msg256"> + <trans-unit id="_msg257"> <source xml:space="preserve">External signer</source> <context-group purpose="location"><context context-type="linenumber">121</context></context-group> </trans-unit> @@ -1142,15 +1146,15 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../createwalletdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="CreateWalletDialog"> - <trans-unit id="_msg257"> + <trans-unit id="_msg258"> <source xml:space="preserve">Create</source> <context-group purpose="location"><context context-type="linenumber">22</context></context-group> </trans-unit> - <trans-unit id="_msg258"> + <trans-unit id="_msg259"> <source xml:space="preserve">Compiled without sqlite support (required for descriptor wallets)</source> <context-group purpose="location"><context context-type="linenumber">90</context></context-group> </trans-unit> - <trans-unit id="_msg259"> + <trans-unit id="_msg260"> <source xml:space="preserve">Compiled without external signing support (required for external signing)</source> <context-group purpose="location"><context context-type="linenumber">104</context></context-group> <note annotates="source" from="developer">"External signing" means using devices such as hardware wallets.</note> @@ -1159,23 +1163,23 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../forms/editaddressdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="EditAddressDialog"> - <trans-unit id="_msg260"> + <trans-unit id="_msg261"> <source xml:space="preserve">Edit Address</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg261"> + <trans-unit id="_msg262"> <source xml:space="preserve">&Label</source> <context-group purpose="location"><context context-type="linenumber">25</context></context-group> </trans-unit> - <trans-unit id="_msg262"> + <trans-unit id="_msg263"> <source xml:space="preserve">The label associated with this address list entry</source> <context-group purpose="location"><context context-type="linenumber">35</context></context-group> </trans-unit> - <trans-unit id="_msg263"> + <trans-unit id="_msg264"> <source xml:space="preserve">The address associated with this address list entry. This can only be modified for sending addresses.</source> <context-group purpose="location"><context context-type="linenumber">52</context></context-group> </trans-unit> - <trans-unit id="_msg264"> + <trans-unit id="_msg265"> <source xml:space="preserve">&Address</source> <context-group purpose="location"><context context-type="linenumber">42</context></context-group> </trans-unit> @@ -1183,35 +1187,35 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../editaddressdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="EditAddressDialog"> - <trans-unit id="_msg265"> + <trans-unit id="_msg266"> <source xml:space="preserve">New sending address</source> <context-group purpose="location"><context context-type="linenumber">29</context></context-group> </trans-unit> - <trans-unit id="_msg266"> + <trans-unit id="_msg267"> <source xml:space="preserve">Edit receiving address</source> <context-group purpose="location"><context context-type="linenumber">32</context></context-group> </trans-unit> - <trans-unit id="_msg267"> + <trans-unit id="_msg268"> <source xml:space="preserve">Edit sending address</source> <context-group purpose="location"><context context-type="linenumber">36</context></context-group> </trans-unit> - <trans-unit id="_msg268"> + <trans-unit id="_msg269"> <source xml:space="preserve">The entered address "%1" is not a valid Bitcoin address.</source> <context-group purpose="location"><context context-type="linenumber">113</context></context-group> </trans-unit> - <trans-unit id="_msg269"> + <trans-unit id="_msg270"> <source xml:space="preserve">Address "%1" already exists as a receiving address with label "%2" and so cannot be added as a sending address.</source> <context-group purpose="location"><context context-type="linenumber">146</context></context-group> </trans-unit> - <trans-unit id="_msg270"> + <trans-unit id="_msg271"> <source xml:space="preserve">The entered address "%1" is already in the address book with label "%2".</source> <context-group purpose="location"><context context-type="linenumber">151</context></context-group> </trans-unit> - <trans-unit id="_msg271"> + <trans-unit id="_msg272"> <source xml:space="preserve">Could not unlock wallet.</source> <context-group purpose="location"><context context-type="linenumber">123</context></context-group> </trans-unit> - <trans-unit id="_msg272"> + <trans-unit id="_msg273"> <source xml:space="preserve">New key generation failed.</source> <context-group purpose="location"><context context-type="linenumber">128</context></context-group> </trans-unit> @@ -1219,90 +1223,90 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../intro.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="FreespaceChecker"> - <trans-unit id="_msg273"> + <trans-unit id="_msg274"> <source xml:space="preserve">A new data directory will be created.</source> <context-group purpose="location"><context context-type="linenumber">73</context></context-group> </trans-unit> - <trans-unit id="_msg274"> + <trans-unit id="_msg275"> <source xml:space="preserve">name</source> <context-group purpose="location"><context context-type="linenumber">95</context></context-group> </trans-unit> - <trans-unit id="_msg275"> + <trans-unit id="_msg276"> <source xml:space="preserve">Directory already exists. Add %1 if you intend to create a new directory here.</source> <context-group purpose="location"><context context-type="linenumber">97</context></context-group> </trans-unit> - <trans-unit id="_msg276"> + <trans-unit id="_msg277"> <source xml:space="preserve">Path already exists, and is not a directory.</source> <context-group purpose="location"><context context-type="linenumber">100</context></context-group> </trans-unit> - <trans-unit id="_msg277"> + <trans-unit id="_msg278"> <source xml:space="preserve">Cannot create data directory here.</source> <context-group purpose="location"><context context-type="linenumber">107</context></context-group> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="Intro"> - <trans-unit id="_msg278"> + <trans-unit id="_msg279"> <source xml:space="preserve">Bitcoin</source> <context-group purpose="location"><context context-type="linenumber">139</context></context-group> </trans-unit> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">301</context></context-group> - <trans-unit id="_msg279[0]"> + <trans-unit id="_msg280[0]"> <source xml:space="preserve">%n GB of space available</source> </trans-unit> - <trans-unit id="_msg279[1]"> + <trans-unit id="_msg280[1]"> <source xml:space="preserve">%n GB of space available</source> </trans-unit> </group> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">303</context></context-group> - <trans-unit id="_msg280[0]"> + <trans-unit id="_msg281[0]"> <source xml:space="preserve">(of %n GB needed)</source> </trans-unit> - <trans-unit id="_msg280[1]"> + <trans-unit id="_msg281[1]"> <source xml:space="preserve">(of %n GB needed)</source> </trans-unit> </group> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">306</context></context-group> - <trans-unit id="_msg281[0]"> + <trans-unit id="_msg282[0]"> <source xml:space="preserve">(%n GB needed for full chain)</source> </trans-unit> - <trans-unit id="_msg281[1]"> + <trans-unit id="_msg282[1]"> <source xml:space="preserve">(%n GB needed for full chain)</source> </trans-unit> </group> - <trans-unit id="_msg282"> + <trans-unit id="_msg283"> <source xml:space="preserve">At least %1 GB of data will be stored in this directory, and it will grow over time.</source> <context-group purpose="location"><context context-type="linenumber">378</context></context-group> </trans-unit> - <trans-unit id="_msg283"> + <trans-unit id="_msg284"> <source xml:space="preserve">Approximately %1 GB of data will be stored in this directory.</source> <context-group purpose="location"><context context-type="linenumber">381</context></context-group> </trans-unit> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">390</context></context-group> <note annotates="source" from="developer">Explanatory text on the capability of the current prune target.</note> - <trans-unit id="_msg284[0]"> + <trans-unit id="_msg285[0]"> <source xml:space="preserve">(sufficient to restore backups %n day(s) old)</source> </trans-unit> - <trans-unit id="_msg284[1]"> + <trans-unit id="_msg285[1]"> <source xml:space="preserve">(sufficient to restore backups %n day(s) old)</source> </trans-unit> </group> - <trans-unit id="_msg285"> + <trans-unit id="_msg286"> <source xml:space="preserve">%1 will download and store a copy of the Bitcoin block chain.</source> <context-group purpose="location"><context context-type="linenumber">392</context></context-group> </trans-unit> - <trans-unit id="_msg286"> + <trans-unit id="_msg287"> <source xml:space="preserve">The wallet will also be stored in this directory.</source> <context-group purpose="location"><context context-type="linenumber">394</context></context-group> </trans-unit> - <trans-unit id="_msg287"> + <trans-unit id="_msg288"> <source xml:space="preserve">Error: Specified data directory "%1" cannot be created.</source> <context-group purpose="location"><context context-type="linenumber">250</context></context-group> </trans-unit> - <trans-unit id="_msg288"> + <trans-unit id="_msg289"> <source xml:space="preserve">Error</source> <context-group purpose="location"><context context-type="linenumber">280</context></context-group> </trans-unit> @@ -1310,25 +1314,25 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../utilitydialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="HelpMessageDialog"> - <trans-unit id="_msg289"> + <trans-unit id="_msg290"> <source xml:space="preserve">version</source> <context-group purpose="location"><context context-type="linenumber">38</context></context-group> </trans-unit> - <trans-unit id="_msg290"> + <trans-unit id="_msg291"> <source xml:space="preserve">About %1</source> <context-group purpose="location"><context context-type="linenumber">42</context></context-group> </trans-unit> - <trans-unit id="_msg291"> + <trans-unit id="_msg292"> <source xml:space="preserve">Command-line options</source> <context-group purpose="location"><context context-type="linenumber">60</context></context-group> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="ShutdownWindow"> - <trans-unit id="_msg292"> + <trans-unit id="_msg293"> <source xml:space="preserve">%1 is shutting down…</source> <context-group purpose="location"><context context-type="linenumber">145</context></context-group> </trans-unit> - <trans-unit id="_msg293"> + <trans-unit id="_msg294"> <source xml:space="preserve">Do not shut down the computer until this window disappears.</source> <context-group purpose="location"><context context-type="linenumber">146</context></context-group> </trans-unit> @@ -1336,47 +1340,47 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../forms/intro.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="Intro"> - <trans-unit id="_msg294"> + <trans-unit id="_msg295"> <source xml:space="preserve">Welcome</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg295"> + <trans-unit id="_msg296"> <source xml:space="preserve">Welcome to %1.</source> <context-group purpose="location"><context context-type="linenumber">23</context></context-group> </trans-unit> - <trans-unit id="_msg296"> + <trans-unit id="_msg297"> <source xml:space="preserve">As this is the first time the program is launched, you can choose where %1 will store its data.</source> <context-group purpose="location"><context context-type="linenumber">49</context></context-group> </trans-unit> - <trans-unit id="_msg297"> + <trans-unit id="_msg298"> <source xml:space="preserve">When you click OK, %1 will begin to download and process the full %4 block chain (%2GB) starting with the earliest transactions in %3 when %4 initially launched.</source> <context-group purpose="location"><context context-type="linenumber">206</context></context-group> </trans-unit> - <trans-unit id="_msg298"> + <trans-unit id="_msg299"> <source xml:space="preserve">Limit block chain storage to</source> <context-group purpose="location"><context context-type="linenumber">238</context></context-group> </trans-unit> - <trans-unit id="_msg299"> + <trans-unit id="_msg300"> <source xml:space="preserve">Reverting this setting requires re-downloading the entire blockchain. It is faster to download the full chain first and prune it later. Disables some advanced features.</source> <context-group purpose="location"><context context-type="linenumber">241</context></context-group> </trans-unit> - <trans-unit id="_msg300"> + <trans-unit id="_msg301"> <source xml:space="preserve"> GB</source> <context-group purpose="location"><context context-type="linenumber">248</context></context-group> </trans-unit> - <trans-unit id="_msg301"> + <trans-unit id="_msg302"> <source xml:space="preserve">This initial synchronisation is very demanding, and may expose hardware problems with your computer that had previously gone unnoticed. Each time you run %1, it will continue downloading where it left off.</source> <context-group purpose="location"><context context-type="linenumber">216</context></context-group> </trans-unit> - <trans-unit id="_msg302"> + <trans-unit id="_msg303"> <source xml:space="preserve">If you have chosen to limit block chain storage (pruning), the historical data must still be downloaded and processed, but will be deleted afterward to keep your disk usage low.</source> <context-group purpose="location"><context context-type="linenumber">226</context></context-group> </trans-unit> - <trans-unit id="_msg303"> + <trans-unit id="_msg304"> <source xml:space="preserve">Use the default data directory</source> <context-group purpose="location"><context context-type="linenumber">66</context></context-group> </trans-unit> - <trans-unit id="_msg304"> + <trans-unit id="_msg305"> <source xml:space="preserve">Use a custom data directory:</source> <context-group purpose="location"><context context-type="linenumber">73</context></context-group> </trans-unit> @@ -1384,54 +1388,54 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../forms/modaloverlay.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="ModalOverlay"> - <trans-unit id="_msg305"> + <trans-unit id="_msg306"> <source xml:space="preserve">Form</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg306"> + <trans-unit id="_msg307"> <source xml:space="preserve">Recent transactions may not yet be visible, and therefore your wallet's balance might be incorrect. This information will be correct once your wallet has finished synchronizing with the bitcoin network, as detailed below.</source> <context-group purpose="location"><context context-type="linenumber">133</context></context-group> </trans-unit> - <trans-unit id="_msg307"> + <trans-unit id="_msg308"> <source xml:space="preserve">Attempting to spend bitcoins that are affected by not-yet-displayed transactions will not be accepted by the network.</source> <context-group purpose="location"><context context-type="linenumber">152</context></context-group> </trans-unit> - <trans-unit id="_msg308"> + <trans-unit id="_msg309"> <source xml:space="preserve">Number of blocks left</source> <context-group purpose="location"><context context-type="linenumber">215</context></context-group> </trans-unit> - <trans-unit id="_msg309"> + <trans-unit id="_msg310"> <source xml:space="preserve">Unknown…</source> <context-group purpose="location"><context context-type="linenumber">222</context></context-group> <context-group purpose="location"><context context-type="linenumber">248</context></context-group> - <context-group purpose="location"><context context-type="sourcefile">../modaloverlay.cpp</context><context context-type="linenumber">152</context></context-group> + <context-group purpose="location"><context context-type="sourcefile">../modaloverlay.cpp</context><context context-type="linenumber">155</context></context-group> </trans-unit> - <trans-unit id="_msg310"> + <trans-unit id="_msg311"> <source xml:space="preserve">calculating…</source> <context-group purpose="location"><context context-type="linenumber">292</context></context-group> <context-group purpose="location"><context context-type="linenumber">312</context></context-group> </trans-unit> - <trans-unit id="_msg311"> + <trans-unit id="_msg312"> <source xml:space="preserve">Last block time</source> <context-group purpose="location"><context context-type="linenumber">235</context></context-group> </trans-unit> - <trans-unit id="_msg312"> + <trans-unit id="_msg313"> <source xml:space="preserve">Progress</source> <context-group purpose="location"><context context-type="linenumber">261</context></context-group> </trans-unit> - <trans-unit id="_msg313"> + <trans-unit id="_msg314"> <source xml:space="preserve">Progress increase per hour</source> <context-group purpose="location"><context context-type="linenumber">285</context></context-group> </trans-unit> - <trans-unit id="_msg314"> + <trans-unit id="_msg315"> <source xml:space="preserve">Estimated time left until synced</source> <context-group purpose="location"><context context-type="linenumber">305</context></context-group> </trans-unit> - <trans-unit id="_msg315"> + <trans-unit id="_msg316"> <source xml:space="preserve">Hide</source> <context-group purpose="location"><context context-type="linenumber">342</context></context-group> </trans-unit> - <trans-unit id="_msg316"> + <trans-unit id="_msg317"> <source xml:space="preserve">Esc</source> <context-group purpose="location"><context context-type="linenumber">345</context></context-group> </trans-unit> @@ -1439,33 +1443,37 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../modaloverlay.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="ModalOverlay"> - <trans-unit id="_msg317"> + <trans-unit id="_msg318"> <source xml:space="preserve">%1 is currently syncing. It will download headers and blocks from peers and validate them until reaching the tip of the block chain.</source> <context-group purpose="location"><context context-type="linenumber">34</context></context-group> </trans-unit> - <trans-unit id="_msg318"> + <trans-unit id="_msg319"> <source xml:space="preserve">Unknown. Syncing Headers (%1, %2%)…</source> - <context-group purpose="location"><context context-type="linenumber">158</context></context-group> + <context-group purpose="location"><context context-type="linenumber">161</context></context-group> + </trans-unit> + <trans-unit id="_msg320"> + <source xml:space="preserve">Unknown. Pre-syncing Headers (%1, %2%)…</source> + <context-group purpose="location"><context context-type="linenumber">166</context></context-group> </trans-unit> </group> <group restype="x-trolltech-linguist-context" resname="QObject"> - <trans-unit id="_msg319"> + <trans-unit id="_msg321"> <source xml:space="preserve">unknown</source> - <context-group purpose="location"><context context-type="linenumber">123</context></context-group> + <context-group purpose="location"><context context-type="linenumber">126</context></context-group> </trans-unit> </group> </body></file> <file original="../forms/openuridialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="OpenURIDialog"> - <trans-unit id="_msg320"> + <trans-unit id="_msg322"> <source xml:space="preserve">Open bitcoin URI</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg321"> + <trans-unit id="_msg323"> <source xml:space="preserve">URI:</source> <context-group purpose="location"><context context-type="linenumber">22</context></context-group> </trans-unit> - <trans-unit id="_msg322"> + <trans-unit id="_msg324"> <source xml:space="preserve">Paste address from clipboard</source> <context-group purpose="location"><context context-type="linenumber">36</context></context-group> <note annotates="source" from="developer">Tooltip text for button that allows you to paste an address that is in your clipboard.</note> @@ -1474,310 +1482,310 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../forms/optionsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="OptionsDialog"> - <trans-unit id="_msg323"> + <trans-unit id="_msg325"> <source xml:space="preserve">Options</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg324"> + <trans-unit id="_msg326"> <source xml:space="preserve">&Main</source> <context-group purpose="location"><context context-type="linenumber">27</context></context-group> </trans-unit> - <trans-unit id="_msg325"> + <trans-unit id="_msg327"> <source xml:space="preserve">Automatically start %1 after logging in to the system.</source> <context-group purpose="location"><context context-type="linenumber">33</context></context-group> </trans-unit> - <trans-unit id="_msg326"> + <trans-unit id="_msg328"> <source xml:space="preserve">&Start %1 on system login</source> <context-group purpose="location"><context context-type="linenumber">36</context></context-group> </trans-unit> - <trans-unit id="_msg327"> + <trans-unit id="_msg329"> <source xml:space="preserve">Enabling pruning significantly reduces the disk space required to store transactions. All blocks are still fully validated. Reverting this setting requires re-downloading the entire blockchain.</source> <context-group purpose="location"><context context-type="linenumber">58</context></context-group> </trans-unit> - <trans-unit id="_msg328"> + <trans-unit id="_msg330"> <source xml:space="preserve">Size of &database cache</source> <context-group purpose="location"><context context-type="linenumber">111</context></context-group> </trans-unit> - <trans-unit id="_msg329"> + <trans-unit id="_msg331"> <source xml:space="preserve">Number of script &verification threads</source> <context-group purpose="location"><context context-type="linenumber">157</context></context-group> </trans-unit> - <trans-unit id="_msg330"> + <trans-unit id="_msg332"> <source xml:space="preserve">IP address of the proxy (e.g. IPv4: 127.0.0.1 / IPv6: ::1)</source> <context-group purpose="location"><context context-type="linenumber">388</context></context-group> <context-group purpose="location"><context context-type="linenumber">575</context></context-group> </trans-unit> - <trans-unit id="_msg331"> + <trans-unit id="_msg333"> <source xml:space="preserve">Shows if the supplied default SOCKS5 proxy is used to reach peers via this network type.</source> <context-group purpose="location"><context context-type="linenumber">457</context></context-group> <context-group purpose="location"><context context-type="linenumber">480</context></context-group> <context-group purpose="location"><context context-type="linenumber">503</context></context-group> </trans-unit> - <trans-unit id="_msg332"> + <trans-unit id="_msg334"> <source xml:space="preserve">Minimize instead of exit the application when the window is closed. When this option is enabled, the application will be closed only after selecting Exit in the menu.</source> <context-group purpose="location"><context context-type="linenumber">672</context></context-group> </trans-unit> - <trans-unit id="_msg333"> + <trans-unit id="_msg335"> <source xml:space="preserve">Options set in this dialog are overridden by the command line:</source> <context-group purpose="location"><context context-type="linenumber">899</context></context-group> </trans-unit> - <trans-unit id="_msg334"> + <trans-unit id="_msg336"> <source xml:space="preserve">Open the %1 configuration file from the working directory.</source> <context-group purpose="location"><context context-type="linenumber">944</context></context-group> </trans-unit> - <trans-unit id="_msg335"> + <trans-unit id="_msg337"> <source xml:space="preserve">Open Configuration File</source> <context-group purpose="location"><context context-type="linenumber">947</context></context-group> </trans-unit> - <trans-unit id="_msg336"> + <trans-unit id="_msg338"> <source xml:space="preserve">Reset all client options to default.</source> <context-group purpose="location"><context context-type="linenumber">957</context></context-group> </trans-unit> - <trans-unit id="_msg337"> + <trans-unit id="_msg339"> <source xml:space="preserve">&Reset Options</source> <context-group purpose="location"><context context-type="linenumber">960</context></context-group> </trans-unit> - <trans-unit id="_msg338"> + <trans-unit id="_msg340"> <source xml:space="preserve">&Network</source> <context-group purpose="location"><context context-type="linenumber">315</context></context-group> </trans-unit> - <trans-unit id="_msg339"> + <trans-unit id="_msg341"> <source xml:space="preserve">Prune &block storage to</source> <context-group purpose="location"><context context-type="linenumber">61</context></context-group> </trans-unit> - <trans-unit id="_msg340"> + <trans-unit id="_msg342"> <source xml:space="preserve">GB</source> <context-group purpose="location"><context context-type="linenumber">71</context></context-group> </trans-unit> - <trans-unit id="_msg341"> + <trans-unit id="_msg343"> <source xml:space="preserve">Reverting this setting requires re-downloading the entire blockchain.</source> <context-group purpose="location"><context context-type="linenumber">96</context></context-group> </trans-unit> - <trans-unit id="_msg342"> + <trans-unit id="_msg344"> <source xml:space="preserve">Maximum database cache size. A larger cache can contribute to faster sync, after which the benefit is less pronounced for most use cases. Lowering the cache size will reduce memory usage. Unused mempool memory is shared for this cache.</source> <context-group purpose="location"><context context-type="linenumber">108</context></context-group> <note annotates="source" from="developer">Tooltip text for Options window setting that sets the size of the database cache. Explains the corresponding effects of increasing/decreasing this value.</note> </trans-unit> - <trans-unit id="_msg343"> + <trans-unit id="_msg345"> <source xml:space="preserve">MiB</source> <context-group purpose="location"><context context-type="linenumber">127</context></context-group> </trans-unit> - <trans-unit id="_msg344"> + <trans-unit id="_msg346"> <source xml:space="preserve">Set the number of script verification threads. Negative values correspond to the number of cores you want to leave free to the system.</source> <context-group purpose="location"><context context-type="linenumber">154</context></context-group> <note annotates="source" from="developer">Tooltip text for Options window setting that sets the number of script verification threads. Explains that negative values mean to leave these many cores free to the system.</note> </trans-unit> - <trans-unit id="_msg345"> + <trans-unit id="_msg347"> <source xml:space="preserve">(0 = auto, <0 = leave that many cores free)</source> <context-group purpose="location"><context context-type="linenumber">170</context></context-group> </trans-unit> - <trans-unit id="_msg346"> + <trans-unit id="_msg348"> <source xml:space="preserve">This allows you or a third party tool to communicate with the node through command-line and JSON-RPC commands.</source> <context-group purpose="location"><context context-type="linenumber">192</context></context-group> <note annotates="source" from="developer">Tooltip text for Options window setting that enables the RPC server.</note> </trans-unit> - <trans-unit id="_msg347"> + <trans-unit id="_msg349"> <source xml:space="preserve">Enable R&PC server</source> <context-group purpose="location"><context context-type="linenumber">195</context></context-group> <note annotates="source" from="developer">An Options window setting to enable the RPC server.</note> </trans-unit> - <trans-unit id="_msg348"> + <trans-unit id="_msg350"> <source xml:space="preserve">W&allet</source> <context-group purpose="location"><context context-type="linenumber">216</context></context-group> </trans-unit> - <trans-unit id="_msg349"> + <trans-unit id="_msg351"> <source xml:space="preserve">Whether to set subtract fee from amount as default or not.</source> <context-group purpose="location"><context context-type="linenumber">222</context></context-group> <note annotates="source" from="developer">Tooltip text for Options window setting that sets subtracting the fee from a sending amount as default.</note> </trans-unit> - <trans-unit id="_msg350"> + <trans-unit id="_msg352"> <source xml:space="preserve">Subtract &fee from amount by default</source> <context-group purpose="location"><context context-type="linenumber">225</context></context-group> <note annotates="source" from="developer">An Options window setting to set subtracting the fee from a sending amount as default.</note> </trans-unit> - <trans-unit id="_msg351"> + <trans-unit id="_msg353"> <source xml:space="preserve">Expert</source> <context-group purpose="location"><context context-type="linenumber">232</context></context-group> </trans-unit> - <trans-unit id="_msg352"> + <trans-unit id="_msg354"> <source xml:space="preserve">Enable coin &control features</source> <context-group purpose="location"><context context-type="linenumber">241</context></context-group> </trans-unit> - <trans-unit id="_msg353"> + <trans-unit id="_msg355"> <source xml:space="preserve">If you disable the spending of unconfirmed change, the change from a transaction cannot be used until that transaction has at least one confirmation. This also affects how your balance is computed.</source> <context-group purpose="location"><context context-type="linenumber">248</context></context-group> </trans-unit> - <trans-unit id="_msg354"> + <trans-unit id="_msg356"> <source xml:space="preserve">&Spend unconfirmed change</source> <context-group purpose="location"><context context-type="linenumber">251</context></context-group> </trans-unit> - <trans-unit id="_msg355"> + <trans-unit id="_msg357"> <source xml:space="preserve">Enable &PSBT controls</source> <context-group purpose="location"><context context-type="linenumber">258</context></context-group> <note annotates="source" from="developer">An options window setting to enable PSBT controls.</note> </trans-unit> - <trans-unit id="_msg356"> + <trans-unit id="_msg358"> <source xml:space="preserve">Whether to show PSBT controls.</source> <context-group purpose="location"><context context-type="linenumber">261</context></context-group> <note annotates="source" from="developer">Tooltip text for options window setting that enables PSBT controls.</note> </trans-unit> - <trans-unit id="_msg357"> + <trans-unit id="_msg359"> <source xml:space="preserve">External Signer (e.g. hardware wallet)</source> <context-group purpose="location"><context context-type="linenumber">271</context></context-group> </trans-unit> - <trans-unit id="_msg358"> + <trans-unit id="_msg360"> <source xml:space="preserve">&External signer script path</source> <context-group purpose="location"><context context-type="linenumber">279</context></context-group> </trans-unit> - <trans-unit id="_msg359"> + <trans-unit id="_msg361"> <source xml:space="preserve">Full path to a Bitcoin Core compatible script (e.g. C:\Downloads\hwi.exe or /Users/you/Downloads/hwi.py). Beware: malware can steal your coins!</source> <context-group purpose="location"><context context-type="linenumber">289</context></context-group> </trans-unit> - <trans-unit id="_msg360"> + <trans-unit id="_msg362"> <source xml:space="preserve">Automatically open the Bitcoin client port on the router. This only works when your router supports UPnP and it is enabled.</source> <context-group purpose="location"><context context-type="linenumber">321</context></context-group> </trans-unit> - <trans-unit id="_msg361"> + <trans-unit id="_msg363"> <source xml:space="preserve">Map port using &UPnP</source> <context-group purpose="location"><context context-type="linenumber">324</context></context-group> </trans-unit> - <trans-unit id="_msg362"> + <trans-unit id="_msg364"> <source xml:space="preserve">Automatically open the Bitcoin client port on the router. This only works when your router supports NAT-PMP and it is enabled. The external port could be random.</source> <context-group purpose="location"><context context-type="linenumber">331</context></context-group> </trans-unit> - <trans-unit id="_msg363"> + <trans-unit id="_msg365"> <source xml:space="preserve">Map port using NA&T-PMP</source> <context-group purpose="location"><context context-type="linenumber">334</context></context-group> </trans-unit> - <trans-unit id="_msg364"> + <trans-unit id="_msg366"> <source xml:space="preserve">Accept connections from outside.</source> <context-group purpose="location"><context context-type="linenumber">341</context></context-group> </trans-unit> - <trans-unit id="_msg365"> + <trans-unit id="_msg367"> <source xml:space="preserve">Allow incomin&g connections</source> <context-group purpose="location"><context context-type="linenumber">344</context></context-group> </trans-unit> - <trans-unit id="_msg366"> + <trans-unit id="_msg368"> <source xml:space="preserve">Connect to the Bitcoin network through a SOCKS5 proxy.</source> <context-group purpose="location"><context context-type="linenumber">351</context></context-group> </trans-unit> - <trans-unit id="_msg367"> + <trans-unit id="_msg369"> <source xml:space="preserve">&Connect through SOCKS5 proxy (default proxy):</source> <context-group purpose="location"><context context-type="linenumber">354</context></context-group> </trans-unit> - <trans-unit id="_msg368"> + <trans-unit id="_msg370"> <source xml:space="preserve">Proxy &IP:</source> <context-group purpose="location"><context context-type="linenumber">363</context></context-group> <context-group purpose="location"><context context-type="linenumber">550</context></context-group> </trans-unit> - <trans-unit id="_msg369"> + <trans-unit id="_msg371"> <source xml:space="preserve">&Port:</source> <context-group purpose="location"><context context-type="linenumber">395</context></context-group> <context-group purpose="location"><context context-type="linenumber">582</context></context-group> </trans-unit> - <trans-unit id="_msg370"> + <trans-unit id="_msg372"> <source xml:space="preserve">Port of the proxy (e.g. 9050)</source> <context-group purpose="location"><context context-type="linenumber">420</context></context-group> <context-group purpose="location"><context context-type="linenumber">607</context></context-group> </trans-unit> - <trans-unit id="_msg371"> + <trans-unit id="_msg373"> <source xml:space="preserve">Used for reaching peers via:</source> <context-group purpose="location"><context context-type="linenumber">444</context></context-group> </trans-unit> - <trans-unit id="_msg372"> + <trans-unit id="_msg374"> <source xml:space="preserve">IPv4</source> <context-group purpose="location"><context context-type="linenumber">467</context></context-group> </trans-unit> - <trans-unit id="_msg373"> + <trans-unit id="_msg375"> <source xml:space="preserve">IPv6</source> <context-group purpose="location"><context context-type="linenumber">490</context></context-group> </trans-unit> - <trans-unit id="_msg374"> + <trans-unit id="_msg376"> <source xml:space="preserve">Tor</source> <context-group purpose="location"><context context-type="linenumber">513</context></context-group> </trans-unit> - <trans-unit id="_msg375"> + <trans-unit id="_msg377"> <source xml:space="preserve">&Window</source> <context-group purpose="location"><context context-type="linenumber">643</context></context-group> </trans-unit> - <trans-unit id="_msg376"> + <trans-unit id="_msg378"> <source xml:space="preserve">Show the icon in the system tray.</source> <context-group purpose="location"><context context-type="linenumber">649</context></context-group> </trans-unit> - <trans-unit id="_msg377"> + <trans-unit id="_msg379"> <source xml:space="preserve">&Show tray icon</source> <context-group purpose="location"><context context-type="linenumber">652</context></context-group> </trans-unit> - <trans-unit id="_msg378"> + <trans-unit id="_msg380"> <source xml:space="preserve">Show only a tray icon after minimizing the window.</source> <context-group purpose="location"><context context-type="linenumber">662</context></context-group> </trans-unit> - <trans-unit id="_msg379"> + <trans-unit id="_msg381"> <source xml:space="preserve">&Minimize to the tray instead of the taskbar</source> <context-group purpose="location"><context context-type="linenumber">665</context></context-group> </trans-unit> - <trans-unit id="_msg380"> + <trans-unit id="_msg382"> <source xml:space="preserve">M&inimize on close</source> <context-group purpose="location"><context context-type="linenumber">675</context></context-group> </trans-unit> - <trans-unit id="_msg381"> + <trans-unit id="_msg383"> <source xml:space="preserve">&Display</source> <context-group purpose="location"><context context-type="linenumber">696</context></context-group> </trans-unit> - <trans-unit id="_msg382"> + <trans-unit id="_msg384"> <source xml:space="preserve">User Interface &language:</source> <context-group purpose="location"><context context-type="linenumber">704</context></context-group> </trans-unit> - <trans-unit id="_msg383"> + <trans-unit id="_msg385"> <source xml:space="preserve">The user interface language can be set here. This setting will take effect after restarting %1.</source> <context-group purpose="location"><context context-type="linenumber">717</context></context-group> </trans-unit> - <trans-unit id="_msg384"> + <trans-unit id="_msg386"> <source xml:space="preserve">&Unit to show amounts in:</source> <context-group purpose="location"><context context-type="linenumber">728</context></context-group> </trans-unit> - <trans-unit id="_msg385"> + <trans-unit id="_msg387"> <source xml:space="preserve">Choose the default subdivision unit to show in the interface and when sending coins.</source> <context-group purpose="location"><context context-type="linenumber">741</context></context-group> </trans-unit> - <trans-unit id="_msg386"> + <trans-unit id="_msg388"> <source xml:space="preserve">Third-party URLs (e.g. a block explorer) that appear in the transactions tab as context menu items. %s in the URL is replaced by transaction hash. Multiple URLs are separated by vertical bar |.</source> <context-group purpose="location"><context context-type="linenumber">752</context></context-group> <context-group purpose="location"><context context-type="linenumber">765</context></context-group> </trans-unit> - <trans-unit id="_msg387"> + <trans-unit id="_msg389"> <source xml:space="preserve">&Third-party transaction URLs</source> <context-group purpose="location"><context context-type="linenumber">755</context></context-group> </trans-unit> - <trans-unit id="_msg388"> + <trans-unit id="_msg390"> <source xml:space="preserve">Whether to show coin control features or not.</source> <context-group purpose="location"><context context-type="linenumber">238</context></context-group> </trans-unit> - <trans-unit id="_msg389"> + <trans-unit id="_msg391"> <source xml:space="preserve">Connect to the Bitcoin network through a separate SOCKS5 proxy for Tor onion services.</source> <context-group purpose="location"><context context-type="linenumber">538</context></context-group> </trans-unit> - <trans-unit id="_msg390"> + <trans-unit id="_msg392"> <source xml:space="preserve">Use separate SOCKS&5 proxy to reach peers via Tor onion services:</source> <context-group purpose="location"><context context-type="linenumber">541</context></context-group> </trans-unit> - <trans-unit id="_msg391"> + <trans-unit id="_msg393"> <source xml:space="preserve">Monospaced font in the Overview tab:</source> <context-group purpose="location"><context context-type="linenumber">777</context></context-group> </trans-unit> - <trans-unit id="_msg392"> + <trans-unit id="_msg394"> <source xml:space="preserve">embedded "%1"</source> <context-group purpose="location"><context context-type="linenumber">785</context></context-group> </trans-unit> - <trans-unit id="_msg393"> + <trans-unit id="_msg395"> <source xml:space="preserve">closest matching "%1"</source> <context-group purpose="location"><context context-type="linenumber">834</context></context-group> </trans-unit> - <trans-unit id="_msg394"> + <trans-unit id="_msg396"> <source xml:space="preserve">&OK</source> <context-group purpose="location"><context context-type="linenumber">1040</context></context-group> </trans-unit> - <trans-unit id="_msg395"> + <trans-unit id="_msg397"> <source xml:space="preserve">&Cancel</source> <context-group purpose="location"><context context-type="linenumber">1053</context></context-group> </trans-unit> @@ -1785,71 +1793,71 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../optionsdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="OptionsDialog"> - <trans-unit id="_msg396"> + <trans-unit id="_msg398"> <source xml:space="preserve">Compiled without external signing support (required for external signing)</source> <context-group purpose="location"><context context-type="linenumber">96</context></context-group> <note annotates="source" from="developer">"External signing" means using devices such as hardware wallets.</note> </trans-unit> - <trans-unit id="_msg397"> + <trans-unit id="_msg399"> <source xml:space="preserve">default</source> <context-group purpose="location"><context context-type="linenumber">108</context></context-group> </trans-unit> - <trans-unit id="_msg398"> + <trans-unit id="_msg400"> <source xml:space="preserve">none</source> <context-group purpose="location"><context context-type="linenumber">194</context></context-group> </trans-unit> - <trans-unit id="_msg399"> + <trans-unit id="_msg401"> <source xml:space="preserve">Confirm options reset</source> <context-group purpose="location"><context context-type="linenumber">301</context></context-group> <note annotates="source" from="developer">Window title text of pop-up window shown when the user has chosen to reset options.</note> </trans-unit> - <trans-unit id="_msg400"> + <trans-unit id="_msg402"> <source xml:space="preserve">Client restart required to activate changes.</source> <context-group purpose="location"><context context-type="linenumber">292</context></context-group> <context-group purpose="location"><context context-type="linenumber">371</context></context-group> <note annotates="source" from="developer">Text explaining that the settings changed will not come into effect until the client is restarted.</note> </trans-unit> - <trans-unit id="_msg401"> + <trans-unit id="_msg403"> <source xml:space="preserve">Current settings will be backed up at "%1".</source> <context-group purpose="location"><context context-type="linenumber">296</context></context-group> <note annotates="source" from="developer">Text explaining to the user that the client's current settings will be backed up at a specific location. %1 is a stand-in argument for the backup location's path.</note> </trans-unit> - <trans-unit id="_msg402"> + <trans-unit id="_msg404"> <source xml:space="preserve">Client will be shut down. Do you want to proceed?</source> <context-group purpose="location"><context context-type="linenumber">299</context></context-group> <note annotates="source" from="developer">Text asking the user to confirm if they would like to proceed with a client shutdown.</note> </trans-unit> - <trans-unit id="_msg403"> + <trans-unit id="_msg405"> <source xml:space="preserve">Configuration options</source> <context-group purpose="location"><context context-type="linenumber">319</context></context-group> <note annotates="source" from="developer">Window title text of pop-up box that allows opening up of configuration file.</note> </trans-unit> - <trans-unit id="_msg404"> + <trans-unit id="_msg406"> <source xml:space="preserve">The configuration file is used to specify advanced user options which override GUI settings. Additionally, any command-line options will override this configuration file.</source> <context-group purpose="location"><context context-type="linenumber">322</context></context-group> <note annotates="source" from="developer">Explanatory text about the priority order of instructions considered by client. The order from high to low being: command-line, configuration file, GUI settings.</note> </trans-unit> - <trans-unit id="_msg405"> + <trans-unit id="_msg407"> <source xml:space="preserve">Continue</source> <context-group purpose="location"><context context-type="linenumber">325</context></context-group> </trans-unit> - <trans-unit id="_msg406"> + <trans-unit id="_msg408"> <source xml:space="preserve">Cancel</source> <context-group purpose="location"><context context-type="linenumber">326</context></context-group> </trans-unit> - <trans-unit id="_msg407"> + <trans-unit id="_msg409"> <source xml:space="preserve">Error</source> <context-group purpose="location"><context context-type="linenumber">335</context></context-group> </trans-unit> - <trans-unit id="_msg408"> + <trans-unit id="_msg410"> <source xml:space="preserve">The configuration file could not be opened.</source> <context-group purpose="location"><context context-type="linenumber">335</context></context-group> </trans-unit> - <trans-unit id="_msg409"> + <trans-unit id="_msg411"> <source xml:space="preserve">This change would require a client restart.</source> <context-group purpose="location"><context context-type="linenumber">375</context></context-group> </trans-unit> - <trans-unit id="_msg410"> + <trans-unit id="_msg412"> <source xml:space="preserve">The supplied proxy address is invalid.</source> <context-group purpose="location"><context context-type="linenumber">403</context></context-group> </trans-unit> @@ -1857,7 +1865,7 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../optionsmodel.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="OptionsModel"> - <trans-unit id="_msg411"> + <trans-unit id="_msg413"> <source xml:space="preserve">Could not read setting "%1", %2.</source> <context-group purpose="location"><context context-type="linenumber">204</context></context-group> </trans-unit> @@ -1865,76 +1873,76 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../forms/overviewpage.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="OverviewPage"> - <trans-unit id="_msg412"> + <trans-unit id="_msg414"> <source xml:space="preserve">Form</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg413"> + <trans-unit id="_msg415"> <source xml:space="preserve">The displayed information may be out of date. Your wallet automatically synchronizes with the Bitcoin network after a connection is established, but this process has not completed yet.</source> <context-group purpose="location"><context context-type="linenumber">76</context></context-group> <context-group purpose="location"><context context-type="linenumber">411</context></context-group> </trans-unit> - <trans-unit id="_msg414"> + <trans-unit id="_msg416"> <source xml:space="preserve">Watch-only:</source> <context-group purpose="location"><context context-type="linenumber">284</context></context-group> </trans-unit> - <trans-unit id="_msg415"> + <trans-unit id="_msg417"> <source xml:space="preserve">Available:</source> <context-group purpose="location"><context context-type="linenumber">294</context></context-group> </trans-unit> - <trans-unit id="_msg416"> + <trans-unit id="_msg418"> <source xml:space="preserve">Your current spendable balance</source> <context-group purpose="location"><context context-type="linenumber">304</context></context-group> </trans-unit> - <trans-unit id="_msg417"> + <trans-unit id="_msg419"> <source xml:space="preserve">Pending:</source> <context-group purpose="location"><context context-type="linenumber">339</context></context-group> </trans-unit> - <trans-unit id="_msg418"> + <trans-unit id="_msg420"> <source xml:space="preserve">Total of transactions that have yet to be confirmed, and do not yet count toward the spendable balance</source> <context-group purpose="location"><context context-type="linenumber">139</context></context-group> </trans-unit> - <trans-unit id="_msg419"> + <trans-unit id="_msg421"> <source xml:space="preserve">Immature:</source> <context-group purpose="location"><context context-type="linenumber">239</context></context-group> </trans-unit> - <trans-unit id="_msg420"> + <trans-unit id="_msg422"> <source xml:space="preserve">Mined balance that has not yet matured</source> <context-group purpose="location"><context context-type="linenumber">210</context></context-group> </trans-unit> - <trans-unit id="_msg421"> + <trans-unit id="_msg423"> <source xml:space="preserve">Balances</source> <context-group purpose="location"><context context-type="linenumber">60</context></context-group> </trans-unit> - <trans-unit id="_msg422"> + <trans-unit id="_msg424"> <source xml:space="preserve">Total:</source> <context-group purpose="location"><context context-type="linenumber">200</context></context-group> </trans-unit> - <trans-unit id="_msg423"> + <trans-unit id="_msg425"> <source xml:space="preserve">Your current total balance</source> <context-group purpose="location"><context context-type="linenumber">249</context></context-group> </trans-unit> - <trans-unit id="_msg424"> + <trans-unit id="_msg426"> <source xml:space="preserve">Your current balance in watch-only addresses</source> <context-group purpose="location"><context context-type="linenumber">323</context></context-group> </trans-unit> - <trans-unit id="_msg425"> + <trans-unit id="_msg427"> <source xml:space="preserve">Spendable:</source> <context-group purpose="location"><context context-type="linenumber">346</context></context-group> </trans-unit> - <trans-unit id="_msg426"> + <trans-unit id="_msg428"> <source xml:space="preserve">Recent transactions</source> <context-group purpose="location"><context context-type="linenumber">395</context></context-group> </trans-unit> - <trans-unit id="_msg427"> + <trans-unit id="_msg429"> <source xml:space="preserve">Unconfirmed transactions to watch-only addresses</source> <context-group purpose="location"><context context-type="linenumber">120</context></context-group> </trans-unit> - <trans-unit id="_msg428"> + <trans-unit id="_msg430"> <source xml:space="preserve">Mined balance in watch-only addresses that has not yet matured</source> <context-group purpose="location"><context context-type="linenumber">158</context></context-group> </trans-unit> - <trans-unit id="_msg429"> + <trans-unit id="_msg431"> <source xml:space="preserve">Current total balance in watch-only addresses</source> <context-group purpose="location"><context context-type="linenumber">268</context></context-group> </trans-unit> @@ -1942,35 +1950,35 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../overviewpage.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="OverviewPage"> - <trans-unit id="_msg430"> + <trans-unit id="_msg432"> <source xml:space="preserve">Privacy mode activated for the Overview tab. To unmask the values, uncheck Settings->Mask values.</source> - <context-group purpose="location"><context context-type="linenumber">186</context></context-group> + <context-group purpose="location"><context context-type="linenumber">185</context></context-group> </trans-unit> </group> </body></file> <file original="../forms/psbtoperationsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="PSBTOperationsDialog"> - <trans-unit id="_msg431"> + <trans-unit id="_msg433"> <source xml:space="preserve">Dialog</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg432"> + <trans-unit id="_msg434"> <source xml:space="preserve">Sign Tx</source> <context-group purpose="location"><context context-type="linenumber">86</context></context-group> </trans-unit> - <trans-unit id="_msg433"> + <trans-unit id="_msg435"> <source xml:space="preserve">Broadcast Tx</source> <context-group purpose="location"><context context-type="linenumber">102</context></context-group> </trans-unit> - <trans-unit id="_msg434"> + <trans-unit id="_msg436"> <source xml:space="preserve">Copy to Clipboard</source> <context-group purpose="location"><context context-type="linenumber">122</context></context-group> </trans-unit> - <trans-unit id="_msg435"> + <trans-unit id="_msg437"> <source xml:space="preserve">Save…</source> <context-group purpose="location"><context context-type="linenumber">129</context></context-group> </trans-unit> - <trans-unit id="_msg436"> + <trans-unit id="_msg438"> <source xml:space="preserve">Close</source> <context-group purpose="location"><context context-type="linenumber">136</context></context-group> </trans-unit> @@ -1978,108 +1986,108 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../psbtoperationsdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="PSBTOperationsDialog"> - <trans-unit id="_msg437"> + <trans-unit id="_msg439"> <source xml:space="preserve">Failed to load transaction: %1</source> <context-group purpose="location"><context context-type="linenumber">61</context></context-group> </trans-unit> - <trans-unit id="_msg438"> + <trans-unit id="_msg440"> <source xml:space="preserve">Failed to sign transaction: %1</source> <context-group purpose="location"><context context-type="linenumber">86</context></context-group> </trans-unit> - <trans-unit id="_msg439"> + <trans-unit id="_msg441"> <source xml:space="preserve">Cannot sign inputs while wallet is locked.</source> <context-group purpose="location"><context context-type="linenumber">94</context></context-group> </trans-unit> - <trans-unit id="_msg440"> + <trans-unit id="_msg442"> <source xml:space="preserve">Could not sign any more inputs.</source> <context-group purpose="location"><context context-type="linenumber">96</context></context-group> </trans-unit> - <trans-unit id="_msg441"> + <trans-unit id="_msg443"> <source xml:space="preserve">Signed %1 inputs, but more signatures are still required.</source> <context-group purpose="location"><context context-type="linenumber">98</context></context-group> </trans-unit> - <trans-unit id="_msg442"> + <trans-unit id="_msg444"> <source xml:space="preserve">Signed transaction successfully. Transaction is ready to broadcast.</source> <context-group purpose="location"><context context-type="linenumber">101</context></context-group> </trans-unit> - <trans-unit id="_msg443"> + <trans-unit id="_msg445"> <source xml:space="preserve">Unknown error processing transaction.</source> <context-group purpose="location"><context context-type="linenumber">113</context></context-group> </trans-unit> - <trans-unit id="_msg444"> + <trans-unit id="_msg446"> <source xml:space="preserve">Transaction broadcast successfully! Transaction ID: %1</source> <context-group purpose="location"><context context-type="linenumber">123</context></context-group> </trans-unit> - <trans-unit id="_msg445"> + <trans-unit id="_msg447"> <source xml:space="preserve">Transaction broadcast failed: %1</source> <context-group purpose="location"><context context-type="linenumber">126</context></context-group> </trans-unit> - <trans-unit id="_msg446"> + <trans-unit id="_msg448"> <source xml:space="preserve">PSBT copied to clipboard.</source> <context-group purpose="location"><context context-type="linenumber">135</context></context-group> </trans-unit> - <trans-unit id="_msg447"> + <trans-unit id="_msg449"> <source xml:space="preserve">Save Transaction Data</source> <context-group purpose="location"><context context-type="linenumber">158</context></context-group> </trans-unit> - <trans-unit id="_msg448"> + <trans-unit id="_msg450"> <source xml:space="preserve">Partially Signed Transaction (Binary)</source> <context-group purpose="location"><context context-type="linenumber">160</context></context-group> <note annotates="source" from="developer">Expanded name of the binary PSBT file format. See: BIP 174.</note> </trans-unit> - <trans-unit id="_msg449"> + <trans-unit id="_msg451"> <source xml:space="preserve">PSBT saved to disk.</source> <context-group purpose="location"><context context-type="linenumber">167</context></context-group> </trans-unit> - <trans-unit id="_msg450"> + <trans-unit id="_msg452"> <source xml:space="preserve"> * Sends %1 to %2</source> <context-group purpose="location"><context context-type="linenumber">183</context></context-group> </trans-unit> - <trans-unit id="_msg451"> + <trans-unit id="_msg453"> <source xml:space="preserve">Unable to calculate transaction fee or total transaction amount.</source> <context-group purpose="location"><context context-type="linenumber">193</context></context-group> </trans-unit> - <trans-unit id="_msg452"> + <trans-unit id="_msg454"> <source xml:space="preserve">Pays transaction fee: </source> <context-group purpose="location"><context context-type="linenumber">195</context></context-group> </trans-unit> - <trans-unit id="_msg453"> + <trans-unit id="_msg455"> <source xml:space="preserve">Total Amount</source> <context-group purpose="location"><context context-type="linenumber">207</context></context-group> </trans-unit> - <trans-unit id="_msg454"> + <trans-unit id="_msg456"> <source xml:space="preserve">or</source> <context-group purpose="location"><context context-type="linenumber">210</context></context-group> </trans-unit> - <trans-unit id="_msg455"> + <trans-unit id="_msg457"> <source xml:space="preserve">Transaction has %1 unsigned inputs.</source> <context-group purpose="location"><context context-type="linenumber">216</context></context-group> </trans-unit> - <trans-unit id="_msg456"> + <trans-unit id="_msg458"> <source xml:space="preserve">Transaction is missing some information about inputs.</source> <context-group purpose="location"><context context-type="linenumber">262</context></context-group> </trans-unit> - <trans-unit id="_msg457"> + <trans-unit id="_msg459"> <source xml:space="preserve">Transaction still needs signature(s).</source> <context-group purpose="location"><context context-type="linenumber">266</context></context-group> </trans-unit> - <trans-unit id="_msg458"> + <trans-unit id="_msg460"> <source xml:space="preserve">(But no wallet is loaded.)</source> <context-group purpose="location"><context context-type="linenumber">269</context></context-group> </trans-unit> - <trans-unit id="_msg459"> + <trans-unit id="_msg461"> <source xml:space="preserve">(But this wallet cannot sign transactions.)</source> <context-group purpose="location"><context context-type="linenumber">272</context></context-group> </trans-unit> - <trans-unit id="_msg460"> + <trans-unit id="_msg462"> <source xml:space="preserve">(But this wallet does not have the right keys.)</source> <context-group purpose="location"><context context-type="linenumber">275</context></context-group> </trans-unit> - <trans-unit id="_msg461"> + <trans-unit id="_msg463"> <source xml:space="preserve">Transaction is fully signed and ready for broadcast.</source> <context-group purpose="location"><context context-type="linenumber">283</context></context-group> </trans-unit> - <trans-unit id="_msg462"> + <trans-unit id="_msg464"> <source xml:space="preserve">Transaction status is unknown.</source> <context-group purpose="location"><context context-type="linenumber">287</context></context-group> </trans-unit> @@ -2087,37 +2095,37 @@ Signing is only possible with addresses of the type 'legacy'.</source> </body></file> <file original="../paymentserver.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="PaymentServer"> - <trans-unit id="_msg463"> + <trans-unit id="_msg465"> <source xml:space="preserve">Payment request error</source> <context-group purpose="location"><context context-type="linenumber">152</context></context-group> </trans-unit> - <trans-unit id="_msg464"> + <trans-unit id="_msg466"> <source xml:space="preserve">Cannot start bitcoin: click-to-pay handler</source> <context-group purpose="location"><context context-type="linenumber">153</context></context-group> </trans-unit> - <trans-unit id="_msg465"> + <trans-unit id="_msg467"> <source xml:space="preserve">URI handling</source> <context-group purpose="location"><context context-type="linenumber">201</context></context-group> <context-group purpose="location"><context context-type="linenumber">217</context></context-group> <context-group purpose="location"><context context-type="linenumber">223</context></context-group> <context-group purpose="location"><context context-type="linenumber">230</context></context-group> </trans-unit> - <trans-unit id="_msg466"> + <trans-unit id="_msg468"> <source xml:space="preserve">'bitcoin://' is not a valid URI. Use 'bitcoin:' instead.</source> <context-group purpose="location"><context context-type="linenumber">201</context></context-group> </trans-unit> - <trans-unit id="_msg467"> + <trans-unit id="_msg469"> <source xml:space="preserve">Cannot process payment request because BIP70 is not supported. Due to widespread security flaws in BIP70 it's strongly recommended that any merchant instructions to switch wallets be ignored. If you are receiving this error you should request the merchant provide a BIP21 compatible URI.</source> <context-group purpose="location"><context context-type="linenumber">218</context></context-group> <context-group purpose="location"><context context-type="linenumber">241</context></context-group> </trans-unit> - <trans-unit id="_msg468"> + <trans-unit id="_msg470"> <source xml:space="preserve">URI cannot be parsed! This can be caused by an invalid Bitcoin address or malformed URI parameters.</source> <context-group purpose="location"><context context-type="linenumber">231</context></context-group> </trans-unit> - <trans-unit id="_msg469"> + <trans-unit id="_msg471"> <source xml:space="preserve">Payment request file handling</source> <context-group purpose="location"><context context-type="linenumber">240</context></context-group> </trans-unit> @@ -2125,52 +2133,52 @@ If you are receiving this error you should request the merchant provide a BIP21 </body></file> <file original="../peertablemodel.h" datatype="c" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="PeerTableModel"> - <trans-unit id="_msg470"> + <trans-unit id="_msg472"> <source xml:space="preserve">User Agent</source> <context-group purpose="location"><context context-type="linenumber">112</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which contains the peer's User Agent string.</note> </trans-unit> - <trans-unit id="_msg471"> + <trans-unit id="_msg473"> <source xml:space="preserve">Ping</source> <context-group purpose="location"><context context-type="linenumber">103</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which indicates the current latency of the connection with the peer.</note> </trans-unit> - <trans-unit id="_msg472"> + <trans-unit id="_msg474"> <source xml:space="preserve">Peer</source> <context-group purpose="location"><context context-type="linenumber">85</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which contains a unique number used to identify a connection.</note> </trans-unit> - <trans-unit id="_msg473"> + <trans-unit id="_msg475"> <source xml:space="preserve">Age</source> <context-group purpose="location"><context context-type="linenumber">88</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which indicates the duration (length of time) since the peer connection started.</note> </trans-unit> - <trans-unit id="_msg474"> + <trans-unit id="_msg476"> <source xml:space="preserve">Direction</source> <context-group purpose="location"><context context-type="linenumber">94</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which indicates the direction the peer connection was initiated from.</note> </trans-unit> - <trans-unit id="_msg475"> + <trans-unit id="_msg477"> <source xml:space="preserve">Sent</source> <context-group purpose="location"><context context-type="linenumber">106</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which indicates the total amount of network information we have sent to the peer.</note> </trans-unit> - <trans-unit id="_msg476"> + <trans-unit id="_msg478"> <source xml:space="preserve">Received</source> <context-group purpose="location"><context context-type="linenumber">109</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which indicates the total amount of network information we have received from the peer.</note> </trans-unit> - <trans-unit id="_msg477"> + <trans-unit id="_msg479"> <source xml:space="preserve">Address</source> <context-group purpose="location"><context context-type="linenumber">91</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which contains the IP/Onion/I2P address of the connected peer.</note> </trans-unit> - <trans-unit id="_msg478"> + <trans-unit id="_msg480"> <source xml:space="preserve">Type</source> <context-group purpose="location"><context context-type="linenumber">97</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which describes the type of peer connection. The "type" describes why the connection exists.</note> </trans-unit> - <trans-unit id="_msg479"> + <trans-unit id="_msg481"> <source xml:space="preserve">Network</source> <context-group purpose="location"><context context-type="linenumber">100</context></context-group> <note annotates="source" from="developer">Title of Peers Table column which states the network the peer connected through.</note> @@ -2179,12 +2187,12 @@ If you are receiving this error you should request the merchant provide a BIP21 </body></file> <file original="../peertablemodel.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="PeerTableModel"> - <trans-unit id="_msg480"> + <trans-unit id="_msg482"> <source xml:space="preserve">Inbound</source> <context-group purpose="location"><context context-type="linenumber">78</context></context-group> <note annotates="source" from="developer">An Inbound Connection from a Peer.</note> </trans-unit> - <trans-unit id="_msg481"> + <trans-unit id="_msg483"> <source xml:space="preserve">Outbound</source> <context-group purpose="location"><context context-type="linenumber">80</context></context-group> <note annotates="source" from="developer">An Outbound Connection to a Peer.</note> @@ -2193,7 +2201,7 @@ If you are receiving this error you should request the merchant provide a BIP21 </body></file> <file original="../bitcoinunits.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="QObject"> - <trans-unit id="_msg482"> + <trans-unit id="_msg484"> <source xml:space="preserve">Amount</source> <context-group purpose="location"><context context-type="linenumber">197</context></context-group> </trans-unit> @@ -2201,162 +2209,162 @@ If you are receiving this error you should request the merchant provide a BIP21 </body></file> <file original="../guiutil.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="QObject"> - <trans-unit id="_msg483"> + <trans-unit id="_msg485"> <source xml:space="preserve">Enter a Bitcoin address (e.g. %1)</source> <context-group purpose="location"><context context-type="linenumber">129</context></context-group> </trans-unit> - <trans-unit id="_msg484"> + <trans-unit id="_msg486"> <source xml:space="preserve">Ctrl+W</source> <context-group purpose="location"><context context-type="linenumber">417</context></context-group> </trans-unit> - <trans-unit id="_msg485"> + <trans-unit id="_msg487"> <source xml:space="preserve">Unroutable</source> <context-group purpose="location"><context context-type="linenumber">673</context></context-group> </trans-unit> - <trans-unit id="_msg486"> + <trans-unit id="_msg488"> <source xml:space="preserve">Internal</source> <context-group purpose="location"><context context-type="linenumber">679</context></context-group> </trans-unit> - <trans-unit id="_msg487"> + <trans-unit id="_msg489"> <source xml:space="preserve">Inbound</source> <context-group purpose="location"><context context-type="linenumber">692</context></context-group> <note annotates="source" from="developer">An inbound connection from a peer. An inbound connection is a connection initiated by a peer.</note> </trans-unit> - <trans-unit id="_msg488"> + <trans-unit id="_msg490"> <source xml:space="preserve">Outbound</source> <context-group purpose="location"><context context-type="linenumber">695</context></context-group> <note annotates="source" from="developer">An outbound connection to a peer. An outbound connection is a connection initiated by us.</note> </trans-unit> - <trans-unit id="_msg489"> + <trans-unit id="_msg491"> <source xml:space="preserve">Full Relay</source> <context-group purpose="location"><context context-type="linenumber">700</context></context-group> <note annotates="source" from="developer">Peer connection type that relays all network information.</note> </trans-unit> - <trans-unit id="_msg490"> + <trans-unit id="_msg492"> <source xml:space="preserve">Block Relay</source> <context-group purpose="location"><context context-type="linenumber">703</context></context-group> <note annotates="source" from="developer">Peer connection type that relays network information about blocks and not transactions or addresses.</note> </trans-unit> - <trans-unit id="_msg491"> + <trans-unit id="_msg493"> <source xml:space="preserve">Manual</source> <context-group purpose="location"><context context-type="linenumber">705</context></context-group> <note annotates="source" from="developer">Peer connection type established manually through one of several methods.</note> </trans-unit> - <trans-unit id="_msg492"> + <trans-unit id="_msg494"> <source xml:space="preserve">Feeler</source> <context-group purpose="location"><context context-type="linenumber">707</context></context-group> <note annotates="source" from="developer">Short-lived peer connection type that tests the aliveness of known addresses.</note> </trans-unit> - <trans-unit id="_msg493"> + <trans-unit id="_msg495"> <source xml:space="preserve">Address Fetch</source> <context-group purpose="location"><context context-type="linenumber">709</context></context-group> <note annotates="source" from="developer">Short-lived peer connection type that solicits known addresses from a peer.</note> </trans-unit> - <trans-unit id="_msg494"> + <trans-unit id="_msg496"> <source xml:space="preserve">%1 d</source> <context-group purpose="location"><context context-type="linenumber">722</context></context-group> <context-group purpose="location"><context context-type="linenumber">734</context></context-group> </trans-unit> - <trans-unit id="_msg495"> + <trans-unit id="_msg497"> <source xml:space="preserve">%1 h</source> <context-group purpose="location"><context context-type="linenumber">723</context></context-group> <context-group purpose="location"><context context-type="linenumber">735</context></context-group> </trans-unit> - <trans-unit id="_msg496"> + <trans-unit id="_msg498"> <source xml:space="preserve">%1 m</source> <context-group purpose="location"><context context-type="linenumber">724</context></context-group> <context-group purpose="location"><context context-type="linenumber">736</context></context-group> </trans-unit> - <trans-unit id="_msg497"> + <trans-unit id="_msg499"> <source xml:space="preserve">%1 s</source> <context-group purpose="location"><context context-type="linenumber">726</context></context-group> <context-group purpose="location"><context context-type="linenumber">737</context></context-group> <context-group purpose="location"><context context-type="linenumber">763</context></context-group> </trans-unit> - <trans-unit id="_msg498"> + <trans-unit id="_msg500"> <source xml:space="preserve">None</source> <context-group purpose="location"><context context-type="linenumber">751</context></context-group> </trans-unit> - <trans-unit id="_msg499"> + <trans-unit id="_msg501"> <source xml:space="preserve">N/A</source> <context-group purpose="location"><context context-type="linenumber">757</context></context-group> </trans-unit> - <trans-unit id="_msg500"> + <trans-unit id="_msg502"> <source xml:space="preserve">%1 ms</source> <context-group purpose="location"><context context-type="linenumber">758</context></context-group> </trans-unit> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">776</context></context-group> - <trans-unit id="_msg501[0]"> + <trans-unit id="_msg503[0]"> <source xml:space="preserve">%n second(s)</source> </trans-unit> - <trans-unit id="_msg501[1]"> + <trans-unit id="_msg503[1]"> <source xml:space="preserve">%n second(s)</source> </trans-unit> </group> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">780</context></context-group> - <trans-unit id="_msg502[0]"> + <trans-unit id="_msg504[0]"> <source xml:space="preserve">%n minute(s)</source> </trans-unit> - <trans-unit id="_msg502[1]"> + <trans-unit id="_msg504[1]"> <source xml:space="preserve">%n minute(s)</source> </trans-unit> </group> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">784</context></context-group> - <trans-unit id="_msg503[0]"> + <trans-unit id="_msg505[0]"> <source xml:space="preserve">%n hour(s)</source> </trans-unit> - <trans-unit id="_msg503[1]"> + <trans-unit id="_msg505[1]"> <source xml:space="preserve">%n hour(s)</source> </trans-unit> </group> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">788</context></context-group> - <trans-unit id="_msg504[0]"> + <trans-unit id="_msg506[0]"> <source xml:space="preserve">%n day(s)</source> </trans-unit> - <trans-unit id="_msg504[1]"> + <trans-unit id="_msg506[1]"> <source xml:space="preserve">%n day(s)</source> </trans-unit> </group> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">792</context></context-group> <context-group purpose="location"><context context-type="linenumber">798</context></context-group> - <trans-unit id="_msg505[0]"> + <trans-unit id="_msg507[0]"> <source xml:space="preserve">%n week(s)</source> </trans-unit> - <trans-unit id="_msg505[1]"> + <trans-unit id="_msg507[1]"> <source xml:space="preserve">%n week(s)</source> </trans-unit> </group> - <trans-unit id="_msg506"> + <trans-unit id="_msg508"> <source xml:space="preserve">%1 and %2</source> <context-group purpose="location"><context context-type="linenumber">798</context></context-group> </trans-unit> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">798</context></context-group> - <trans-unit id="_msg507[0]"> + <trans-unit id="_msg509[0]"> <source xml:space="preserve">%n year(s)</source> </trans-unit> - <trans-unit id="_msg507[1]"> + <trans-unit id="_msg509[1]"> <source xml:space="preserve">%n year(s)</source> </trans-unit> </group> - <trans-unit id="_msg508"> + <trans-unit id="_msg510"> <source xml:space="preserve">%1 B</source> <context-group purpose="location"><context context-type="linenumber">806</context></context-group> </trans-unit> - <trans-unit id="_msg509"> + <trans-unit id="_msg511"> <source xml:space="preserve">%1 kB</source> <context-group purpose="location"><context context-type="linenumber">808</context></context-group> </trans-unit> - <trans-unit id="_msg510"> + <trans-unit id="_msg512"> <source xml:space="preserve">%1 MB</source> <context-group purpose="location"><context context-type="linenumber">810</context></context-group> </trans-unit> - <trans-unit id="_msg511"> + <trans-unit id="_msg513"> <source xml:space="preserve">%1 GB</source> <context-group purpose="location"><context context-type="linenumber">812</context></context-group> </trans-unit> @@ -2364,31 +2372,31 @@ If you are receiving this error you should request the merchant provide a BIP21 </body></file> <file original="../qrimagewidget.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="QRImageWidget"> - <trans-unit id="_msg512"> + <trans-unit id="_msg514"> <source xml:space="preserve">&Save Image…</source> <context-group purpose="location"><context context-type="linenumber">30</context></context-group> </trans-unit> - <trans-unit id="_msg513"> + <trans-unit id="_msg515"> <source xml:space="preserve">&Copy Image</source> <context-group purpose="location"><context context-type="linenumber">31</context></context-group> </trans-unit> - <trans-unit id="_msg514"> + <trans-unit id="_msg516"> <source xml:space="preserve">Resulting URI too long, try to reduce the text for label / message.</source> <context-group purpose="location"><context context-type="linenumber">42</context></context-group> </trans-unit> - <trans-unit id="_msg515"> + <trans-unit id="_msg517"> <source xml:space="preserve">Error encoding URI into QR Code.</source> <context-group purpose="location"><context context-type="linenumber">49</context></context-group> </trans-unit> - <trans-unit id="_msg516"> + <trans-unit id="_msg518"> <source xml:space="preserve">QR code support not available.</source> <context-group purpose="location"><context context-type="linenumber">90</context></context-group> </trans-unit> - <trans-unit id="_msg517"> + <trans-unit id="_msg519"> <source xml:space="preserve">Save QR Code</source> <context-group purpose="location"><context context-type="linenumber">120</context></context-group> </trans-unit> - <trans-unit id="_msg518"> + <trans-unit id="_msg520"> <source xml:space="preserve">PNG Image</source> <context-group purpose="location"><context context-type="linenumber">123</context></context-group> <note annotates="source" from="developer">Expanded name of the PNG file format. See: https://en.wikipedia.org/wiki/Portable_Network_Graphics.</note> @@ -2397,7 +2405,7 @@ If you are receiving this error you should request the merchant provide a BIP21 </body></file> <file original="../forms/debugwindow.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="RPCConsole"> - <trans-unit id="_msg519"> + <trans-unit id="_msg521"> <source xml:space="preserve">N/A</source> <context-group purpose="location"><context context-type="linenumber">75</context></context-group> <context-group purpose="location"><context context-type="linenumber">101</context></context-group> @@ -2438,291 +2446,291 @@ If you are receiving this error you should request the merchant provide a BIP21 <context-group purpose="location"><context context-type="linenumber">1662</context></context-group> <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.h</context><context context-type="linenumber">143</context></context-group> </trans-unit> - <trans-unit id="_msg520"> + <trans-unit id="_msg522"> <source xml:space="preserve">Client version</source> <context-group purpose="location"><context context-type="linenumber">65</context></context-group> </trans-unit> - <trans-unit id="_msg521"> + <trans-unit id="_msg523"> <source xml:space="preserve">&Information</source> <context-group purpose="location"><context context-type="linenumber">43</context></context-group> </trans-unit> - <trans-unit id="_msg522"> + <trans-unit id="_msg524"> <source xml:space="preserve">General</source> <context-group purpose="location"><context context-type="linenumber">58</context></context-group> </trans-unit> - <trans-unit id="_msg523"> + <trans-unit id="_msg525"> <source xml:space="preserve">Datadir</source> <context-group purpose="location"><context context-type="linenumber">114</context></context-group> </trans-unit> - <trans-unit id="_msg524"> + <trans-unit id="_msg526"> <source xml:space="preserve">To specify a non-default location of the data directory use the '%1' option.</source> <context-group purpose="location"><context context-type="linenumber">124</context></context-group> </trans-unit> - <trans-unit id="_msg525"> + <trans-unit id="_msg527"> <source xml:space="preserve">Blocksdir</source> <context-group purpose="location"><context context-type="linenumber">143</context></context-group> </trans-unit> - <trans-unit id="_msg526"> + <trans-unit id="_msg528"> <source xml:space="preserve">To specify a non-default location of the blocks directory use the '%1' option.</source> <context-group purpose="location"><context context-type="linenumber">153</context></context-group> </trans-unit> - <trans-unit id="_msg527"> + <trans-unit id="_msg529"> <source xml:space="preserve">Startup time</source> <context-group purpose="location"><context context-type="linenumber">172</context></context-group> </trans-unit> - <trans-unit id="_msg528"> + <trans-unit id="_msg530"> <source xml:space="preserve">Network</source> <context-group purpose="location"><context context-type="linenumber">201</context></context-group> <context-group purpose="location"><context context-type="linenumber">1093</context></context-group> </trans-unit> - <trans-unit id="_msg529"> + <trans-unit id="_msg531"> <source xml:space="preserve">Name</source> <context-group purpose="location"><context context-type="linenumber">208</context></context-group> </trans-unit> - <trans-unit id="_msg530"> + <trans-unit id="_msg532"> <source xml:space="preserve">Number of connections</source> <context-group purpose="location"><context context-type="linenumber">231</context></context-group> </trans-unit> - <trans-unit id="_msg531"> + <trans-unit id="_msg533"> <source xml:space="preserve">Block chain</source> <context-group purpose="location"><context context-type="linenumber">260</context></context-group> </trans-unit> - <trans-unit id="_msg532"> + <trans-unit id="_msg534"> <source xml:space="preserve">Memory Pool</source> <context-group purpose="location"><context context-type="linenumber">319</context></context-group> </trans-unit> - <trans-unit id="_msg533"> + <trans-unit id="_msg535"> <source xml:space="preserve">Current number of transactions</source> <context-group purpose="location"><context context-type="linenumber">326</context></context-group> </trans-unit> - <trans-unit id="_msg534"> + <trans-unit id="_msg536"> <source xml:space="preserve">Memory usage</source> <context-group purpose="location"><context context-type="linenumber">349</context></context-group> </trans-unit> - <trans-unit id="_msg535"> + <trans-unit id="_msg537"> <source xml:space="preserve">Wallet: </source> <context-group purpose="location"><context context-type="linenumber">443</context></context-group> </trans-unit> - <trans-unit id="_msg536"> + <trans-unit id="_msg538"> <source xml:space="preserve">(none)</source> <context-group purpose="location"><context context-type="linenumber">454</context></context-group> </trans-unit> - <trans-unit id="_msg537"> + <trans-unit id="_msg539"> <source xml:space="preserve">&Reset</source> <context-group purpose="location"><context context-type="linenumber">665</context></context-group> </trans-unit> - <trans-unit id="_msg538"> + <trans-unit id="_msg540"> <source xml:space="preserve">Received</source> <context-group purpose="location"><context context-type="linenumber">745</context></context-group> <context-group purpose="location"><context context-type="linenumber">1453</context></context-group> </trans-unit> - <trans-unit id="_msg539"> + <trans-unit id="_msg541"> <source xml:space="preserve">Sent</source> <context-group purpose="location"><context context-type="linenumber">825</context></context-group> <context-group purpose="location"><context context-type="linenumber">1430</context></context-group> </trans-unit> - <trans-unit id="_msg540"> + <trans-unit id="_msg542"> <source xml:space="preserve">&Peers</source> <context-group purpose="location"><context context-type="linenumber">866</context></context-group> </trans-unit> - <trans-unit id="_msg541"> + <trans-unit id="_msg543"> <source xml:space="preserve">Banned peers</source> <context-group purpose="location"><context context-type="linenumber">942</context></context-group> </trans-unit> - <trans-unit id="_msg542"> + <trans-unit id="_msg544"> <source xml:space="preserve">Select a peer to view detailed information.</source> <context-group purpose="location"><context context-type="linenumber">1010</context></context-group> <context-group purpose="location"><context context-type="sourcefile">../rpcconsole.cpp</context><context context-type="linenumber">1155</context></context-group> </trans-unit> - <trans-unit id="_msg543"> + <trans-unit id="_msg545"> <source xml:space="preserve">Version</source> <context-group purpose="location"><context context-type="linenumber">1116</context></context-group> </trans-unit> - <trans-unit id="_msg544"> + <trans-unit id="_msg546"> <source xml:space="preserve">Starting Block</source> <context-group purpose="location"><context context-type="linenumber">1240</context></context-group> </trans-unit> - <trans-unit id="_msg545"> + <trans-unit id="_msg547"> <source xml:space="preserve">Synced Headers</source> <context-group purpose="location"><context context-type="linenumber">1263</context></context-group> </trans-unit> - <trans-unit id="_msg546"> + <trans-unit id="_msg548"> <source xml:space="preserve">Synced Blocks</source> <context-group purpose="location"><context context-type="linenumber">1286</context></context-group> </trans-unit> - <trans-unit id="_msg547"> + <trans-unit id="_msg549"> <source xml:space="preserve">Last Transaction</source> <context-group purpose="location"><context context-type="linenumber">1361</context></context-group> </trans-unit> - <trans-unit id="_msg548"> + <trans-unit id="_msg550"> <source xml:space="preserve">The mapped Autonomous System used for diversifying peer selection.</source> <context-group purpose="location"><context context-type="linenumber">1571</context></context-group> </trans-unit> - <trans-unit id="_msg549"> + <trans-unit id="_msg551"> <source xml:space="preserve">Mapped AS</source> <context-group purpose="location"><context context-type="linenumber">1574</context></context-group> </trans-unit> - <trans-unit id="_msg550"> + <trans-unit id="_msg552"> <source xml:space="preserve">Whether we relay addresses to this peer.</source> <context-group purpose="location"><context context-type="linenumber">1597</context></context-group> <note annotates="source" from="developer">Tooltip text for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No).</note> </trans-unit> - <trans-unit id="_msg551"> + <trans-unit id="_msg553"> <source xml:space="preserve">Address Relay</source> <context-group purpose="location"><context context-type="linenumber">1600</context></context-group> <note annotates="source" from="developer">Text title for the Address Relay field in the peer details area, which displays whether we relay addresses to this peer (Yes/No).</note> </trans-unit> - <trans-unit id="_msg552"> + <trans-unit id="_msg554"> <source xml:space="preserve">The total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).</source> <context-group purpose="location"><context context-type="linenumber">1623</context></context-group> <note annotates="source" from="developer">Tooltip text for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).</note> </trans-unit> - <trans-unit id="_msg553"> + <trans-unit id="_msg555"> <source xml:space="preserve">The total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.</source> <context-group purpose="location"><context context-type="linenumber">1649</context></context-group> <note annotates="source" from="developer">Tooltip text for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.</note> </trans-unit> - <trans-unit id="_msg554"> + <trans-unit id="_msg556"> <source xml:space="preserve">Addresses Processed</source> <context-group purpose="location"><context context-type="linenumber">1626</context></context-group> <note annotates="source" from="developer">Text title for the Addresses Processed field in the peer details area, which displays the total number of addresses received from this peer that were processed (excludes addresses that were dropped due to rate-limiting).</note> </trans-unit> - <trans-unit id="_msg555"> + <trans-unit id="_msg557"> <source xml:space="preserve">Addresses Rate-Limited</source> <context-group purpose="location"><context context-type="linenumber">1652</context></context-group> <note annotates="source" from="developer">Text title for the Addresses Rate-Limited field in the peer details area, which displays the total number of addresses received from this peer that were dropped (not processed) due to rate-limiting.</note> </trans-unit> - <trans-unit id="_msg556"> + <trans-unit id="_msg558"> <source xml:space="preserve">User Agent</source> <context-group purpose="location"><context context-type="linenumber">88</context></context-group> <context-group purpose="location"><context context-type="linenumber">1139</context></context-group> </trans-unit> - <trans-unit id="_msg557"> + <trans-unit id="_msg559"> <source xml:space="preserve">Node window</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg558"> + <trans-unit id="_msg560"> <source xml:space="preserve">Current block height</source> <context-group purpose="location"><context context-type="linenumber">267</context></context-group> </trans-unit> - <trans-unit id="_msg559"> + <trans-unit id="_msg561"> <source xml:space="preserve">Open the %1 debug log file from the current data directory. This can take a few seconds for large log files.</source> <context-group purpose="location"><context context-type="linenumber">397</context></context-group> </trans-unit> - <trans-unit id="_msg560"> + <trans-unit id="_msg562"> <source xml:space="preserve">Decrease font size</source> <context-group purpose="location"><context context-type="linenumber">475</context></context-group> </trans-unit> - <trans-unit id="_msg561"> + <trans-unit id="_msg563"> <source xml:space="preserve">Increase font size</source> <context-group purpose="location"><context context-type="linenumber">495</context></context-group> </trans-unit> - <trans-unit id="_msg562"> + <trans-unit id="_msg564"> <source xml:space="preserve">Permissions</source> <context-group purpose="location"><context context-type="linenumber">1041</context></context-group> </trans-unit> - <trans-unit id="_msg563"> + <trans-unit id="_msg565"> <source xml:space="preserve">The direction and type of peer connection: %1</source> <context-group purpose="location"><context context-type="linenumber">1064</context></context-group> </trans-unit> - <trans-unit id="_msg564"> + <trans-unit id="_msg566"> <source xml:space="preserve">Direction/Type</source> <context-group purpose="location"><context context-type="linenumber">1067</context></context-group> </trans-unit> - <trans-unit id="_msg565"> + <trans-unit id="_msg567"> <source xml:space="preserve">The network protocol this peer is connected through: IPv4, IPv6, Onion, I2P, or CJDNS.</source> <context-group purpose="location"><context context-type="linenumber">1090</context></context-group> </trans-unit> - <trans-unit id="_msg566"> + <trans-unit id="_msg568"> <source xml:space="preserve">Services</source> <context-group purpose="location"><context context-type="linenumber">1162</context></context-group> </trans-unit> - <trans-unit id="_msg567"> + <trans-unit id="_msg569"> <source xml:space="preserve">Whether the peer requested us to relay transactions.</source> <context-group purpose="location"><context context-type="linenumber">1188</context></context-group> </trans-unit> - <trans-unit id="_msg568"> + <trans-unit id="_msg570"> <source xml:space="preserve">Wants Tx Relay</source> <context-group purpose="location"><context context-type="linenumber">1191</context></context-group> </trans-unit> - <trans-unit id="_msg569"> + <trans-unit id="_msg571"> <source xml:space="preserve">High bandwidth BIP152 compact block relay: %1</source> <context-group purpose="location"><context context-type="linenumber">1214</context></context-group> </trans-unit> - <trans-unit id="_msg570"> + <trans-unit id="_msg572"> <source xml:space="preserve">High Bandwidth</source> <context-group purpose="location"><context context-type="linenumber">1217</context></context-group> </trans-unit> - <trans-unit id="_msg571"> + <trans-unit id="_msg573"> <source xml:space="preserve">Connection Time</source> <context-group purpose="location"><context context-type="linenumber">1309</context></context-group> </trans-unit> - <trans-unit id="_msg572"> + <trans-unit id="_msg574"> <source xml:space="preserve">Elapsed time since a novel block passing initial validity checks was received from this peer.</source> <context-group purpose="location"><context context-type="linenumber">1332</context></context-group> </trans-unit> - <trans-unit id="_msg573"> + <trans-unit id="_msg575"> <source xml:space="preserve">Last Block</source> <context-group purpose="location"><context context-type="linenumber">1335</context></context-group> </trans-unit> - <trans-unit id="_msg574"> + <trans-unit id="_msg576"> <source xml:space="preserve">Elapsed time since a novel transaction accepted into our mempool was received from this peer.</source> <context-group purpose="location"><context context-type="linenumber">1358</context></context-group> <note annotates="source" from="developer">Tooltip text for the Last Transaction field in the peer details area.</note> </trans-unit> - <trans-unit id="_msg575"> + <trans-unit id="_msg577"> <source xml:space="preserve">Last Send</source> <context-group purpose="location"><context context-type="linenumber">1384</context></context-group> </trans-unit> - <trans-unit id="_msg576"> + <trans-unit id="_msg578"> <source xml:space="preserve">Last Receive</source> <context-group purpose="location"><context context-type="linenumber">1407</context></context-group> </trans-unit> - <trans-unit id="_msg577"> + <trans-unit id="_msg579"> <source xml:space="preserve">Ping Time</source> <context-group purpose="location"><context context-type="linenumber">1476</context></context-group> </trans-unit> - <trans-unit id="_msg578"> + <trans-unit id="_msg580"> <source xml:space="preserve">The duration of a currently outstanding ping.</source> <context-group purpose="location"><context context-type="linenumber">1499</context></context-group> </trans-unit> - <trans-unit id="_msg579"> + <trans-unit id="_msg581"> <source xml:space="preserve">Ping Wait</source> <context-group purpose="location"><context context-type="linenumber">1502</context></context-group> </trans-unit> - <trans-unit id="_msg580"> + <trans-unit id="_msg582"> <source xml:space="preserve">Min Ping</source> <context-group purpose="location"><context context-type="linenumber">1525</context></context-group> </trans-unit> - <trans-unit id="_msg581"> + <trans-unit id="_msg583"> <source xml:space="preserve">Time Offset</source> <context-group purpose="location"><context context-type="linenumber">1548</context></context-group> </trans-unit> - <trans-unit id="_msg582"> + <trans-unit id="_msg584"> <source xml:space="preserve">Last block time</source> <context-group purpose="location"><context context-type="linenumber">290</context></context-group> </trans-unit> - <trans-unit id="_msg583"> + <trans-unit id="_msg585"> <source xml:space="preserve">&Open</source> <context-group purpose="location"><context context-type="linenumber">400</context></context-group> </trans-unit> - <trans-unit id="_msg584"> + <trans-unit id="_msg586"> <source xml:space="preserve">&Console</source> <context-group purpose="location"><context context-type="linenumber">426</context></context-group> </trans-unit> - <trans-unit id="_msg585"> + <trans-unit id="_msg587"> <source xml:space="preserve">&Network Traffic</source> <context-group purpose="location"><context context-type="linenumber">613</context></context-group> </trans-unit> - <trans-unit id="_msg586"> + <trans-unit id="_msg588"> <source xml:space="preserve">Totals</source> <context-group purpose="location"><context context-type="linenumber">681</context></context-group> </trans-unit> - <trans-unit id="_msg587"> + <trans-unit id="_msg589"> <source xml:space="preserve">Debug log file</source> <context-group purpose="location"><context context-type="linenumber">390</context></context-group> </trans-unit> - <trans-unit id="_msg588"> + <trans-unit id="_msg590"> <source xml:space="preserve">Clear console</source> <context-group purpose="location"><context context-type="linenumber">515</context></context-group> </trans-unit> @@ -2730,139 +2738,139 @@ If you are receiving this error you should request the merchant provide a BIP21 </body></file> <file original="../rpcconsole.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="RPCConsole"> - <trans-unit id="_msg589"> + <trans-unit id="_msg591"> <source xml:space="preserve">In:</source> <context-group purpose="location"><context context-type="linenumber">953</context></context-group> </trans-unit> - <trans-unit id="_msg590"> + <trans-unit id="_msg592"> <source xml:space="preserve">Out:</source> <context-group purpose="location"><context context-type="linenumber">954</context></context-group> </trans-unit> - <trans-unit id="_msg591"> + <trans-unit id="_msg593"> <source xml:space="preserve">Inbound: initiated by peer</source> <context-group purpose="location"><context context-type="linenumber">496</context></context-group> <note annotates="source" from="developer">Explanatory text for an inbound peer connection.</note> </trans-unit> - <trans-unit id="_msg592"> + <trans-unit id="_msg594"> <source xml:space="preserve">Outbound Full Relay: default</source> <context-group purpose="location"><context context-type="linenumber">500</context></context-group> <note annotates="source" from="developer">Explanatory text for an outbound peer connection that relays all network information. This is the default behavior for outbound connections.</note> </trans-unit> - <trans-unit id="_msg593"> + <trans-unit id="_msg595"> <source xml:space="preserve">Outbound Block Relay: does not relay transactions or addresses</source> <context-group purpose="location"><context context-type="linenumber">503</context></context-group> <note annotates="source" from="developer">Explanatory text for an outbound peer connection that relays network information about blocks and not transactions or addresses.</note> </trans-unit> - <trans-unit id="_msg594"> + <trans-unit id="_msg596"> <source xml:space="preserve">Outbound Manual: added using RPC %1 or %2/%3 configuration options</source> <context-group purpose="location"><context context-type="linenumber">508</context></context-group> <note annotates="source" from="developer">Explanatory text for an outbound peer connection that was established manually through one of several methods. The numbered arguments are stand-ins for the methods available to establish manual connections.</note> </trans-unit> - <trans-unit id="_msg595"> + <trans-unit id="_msg597"> <source xml:space="preserve">Outbound Feeler: short-lived, for testing addresses</source> <context-group purpose="location"><context context-type="linenumber">514</context></context-group> <note annotates="source" from="developer">Explanatory text for a short-lived outbound peer connection that is used to test the aliveness of known addresses.</note> </trans-unit> - <trans-unit id="_msg596"> + <trans-unit id="_msg598"> <source xml:space="preserve">Outbound Address Fetch: short-lived, for soliciting addresses</source> <context-group purpose="location"><context context-type="linenumber">517</context></context-group> <note annotates="source" from="developer">Explanatory text for a short-lived outbound peer connection that is used to request addresses from a peer.</note> </trans-unit> - <trans-unit id="_msg597"> + <trans-unit id="_msg599"> <source xml:space="preserve">we selected the peer for high bandwidth relay</source> <context-group purpose="location"><context context-type="linenumber">521</context></context-group> </trans-unit> - <trans-unit id="_msg598"> + <trans-unit id="_msg600"> <source xml:space="preserve">the peer selected us for high bandwidth relay</source> <context-group purpose="location"><context context-type="linenumber">522</context></context-group> </trans-unit> - <trans-unit id="_msg599"> + <trans-unit id="_msg601"> <source xml:space="preserve">no high bandwidth relay selected</source> <context-group purpose="location"><context context-type="linenumber">523</context></context-group> </trans-unit> - <trans-unit id="_msg600"> + <trans-unit id="_msg602"> <source xml:space="preserve">Ctrl++</source> <context-group purpose="location"><context context-type="linenumber">536</context></context-group> <note annotates="source" from="developer">Main shortcut to increase the RPC console font size.</note> </trans-unit> - <trans-unit id="_msg601"> + <trans-unit id="_msg603"> <source xml:space="preserve">Ctrl+=</source> <context-group purpose="location"><context context-type="linenumber">538</context></context-group> <note annotates="source" from="developer">Secondary shortcut to increase the RPC console font size.</note> </trans-unit> - <trans-unit id="_msg602"> + <trans-unit id="_msg604"> <source xml:space="preserve">Ctrl+-</source> <context-group purpose="location"><context context-type="linenumber">542</context></context-group> <note annotates="source" from="developer">Main shortcut to decrease the RPC console font size.</note> </trans-unit> - <trans-unit id="_msg603"> + <trans-unit id="_msg605"> <source xml:space="preserve">Ctrl+_</source> <context-group purpose="location"><context context-type="linenumber">544</context></context-group> <note annotates="source" from="developer">Secondary shortcut to decrease the RPC console font size.</note> </trans-unit> - <trans-unit id="_msg604"> + <trans-unit id="_msg606"> <source xml:space="preserve">&Copy address</source> <context-group purpose="location"><context context-type="linenumber">695</context></context-group> <note annotates="source" from="developer">Context menu action to copy the address of a peer.</note> </trans-unit> - <trans-unit id="_msg605"> + <trans-unit id="_msg607"> <source xml:space="preserve">&Disconnect</source> <context-group purpose="location"><context context-type="linenumber">699</context></context-group> </trans-unit> - <trans-unit id="_msg606"> + <trans-unit id="_msg608"> <source xml:space="preserve">1 &hour</source> <context-group purpose="location"><context context-type="linenumber">700</context></context-group> </trans-unit> - <trans-unit id="_msg607"> + <trans-unit id="_msg609"> <source xml:space="preserve">1 d&ay</source> <context-group purpose="location"><context context-type="linenumber">701</context></context-group> </trans-unit> - <trans-unit id="_msg608"> + <trans-unit id="_msg610"> <source xml:space="preserve">1 &week</source> <context-group purpose="location"><context context-type="linenumber">702</context></context-group> </trans-unit> - <trans-unit id="_msg609"> + <trans-unit id="_msg611"> <source xml:space="preserve">1 &year</source> <context-group purpose="location"><context context-type="linenumber">703</context></context-group> </trans-unit> - <trans-unit id="_msg610"> + <trans-unit id="_msg612"> <source xml:space="preserve">&Copy IP/Netmask</source> <context-group purpose="location"><context context-type="linenumber">729</context></context-group> <note annotates="source" from="developer">Context menu action to copy the IP/Netmask of a banned peer. IP/Netmask is the combination of a peer's IP address and its Netmask. For IP address, see: https://en.wikipedia.org/wiki/IP_address.</note> </trans-unit> - <trans-unit id="_msg611"> + <trans-unit id="_msg613"> <source xml:space="preserve">&Unban</source> <context-group purpose="location"><context context-type="linenumber">733</context></context-group> </trans-unit> - <trans-unit id="_msg612"> + <trans-unit id="_msg614"> <source xml:space="preserve">Network activity disabled</source> <context-group purpose="location"><context context-type="linenumber">957</context></context-group> </trans-unit> - <trans-unit id="_msg613"> + <trans-unit id="_msg615"> <source xml:space="preserve">Executing command without any wallet</source> <context-group purpose="location"><context context-type="linenumber">1035</context></context-group> </trans-unit> - <trans-unit id="_msg614"> + <trans-unit id="_msg616"> <source xml:space="preserve">Ctrl+I</source> <context-group purpose="location"><context context-type="linenumber">1351</context></context-group> </trans-unit> - <trans-unit id="_msg615"> + <trans-unit id="_msg617"> <source xml:space="preserve">Ctrl+T</source> <context-group purpose="location"><context context-type="linenumber">1352</context></context-group> </trans-unit> - <trans-unit id="_msg616"> + <trans-unit id="_msg618"> <source xml:space="preserve">Ctrl+N</source> <context-group purpose="location"><context context-type="linenumber">1353</context></context-group> </trans-unit> - <trans-unit id="_msg617"> + <trans-unit id="_msg619"> <source xml:space="preserve">Ctrl+P</source> <context-group purpose="location"><context context-type="linenumber">1354</context></context-group> </trans-unit> - <trans-unit id="_msg618"> + <trans-unit id="_msg620"> <source xml:space="preserve">Executing command using "%1" wallet</source> <context-group purpose="location"><context context-type="linenumber">1033</context></context-group> </trans-unit> - <trans-unit id="_msg619"> + <trans-unit id="_msg621"> <source xml:space="preserve">Welcome to the %1 RPC console. Use up and down arrows to navigate history, and %2 to clear screen. Use %3 and %4 to increase or decrease the font size. @@ -2873,16 +2881,16 @@ For more information on using this console, type %6. <context-group purpose="location"><context context-type="linenumber">887</context></context-group> <note annotates="source" from="developer">RPC console welcome message. Placeholders %7 and %8 are style tags for the warning content, and they are not space separated from the rest of the text intentionally.</note> </trans-unit> - <trans-unit id="_msg620"> + <trans-unit id="_msg622"> <source xml:space="preserve">Executing…</source> <context-group purpose="location"><context context-type="linenumber">1043</context></context-group> <note annotates="source" from="developer">A console message indicating an entered command is currently being executed.</note> </trans-unit> - <trans-unit id="_msg621"> + <trans-unit id="_msg623"> <source xml:space="preserve">(peer: %1)</source> <context-group purpose="location"><context context-type="linenumber">1161</context></context-group> </trans-unit> - <trans-unit id="_msg622"> + <trans-unit id="_msg624"> <source xml:space="preserve">via %1</source> <context-group purpose="location"><context context-type="linenumber">1163</context></context-group> </trans-unit> @@ -2890,31 +2898,31 @@ For more information on using this console, type %6. </body></file> <file original="../rpcconsole.h" datatype="c" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="RPCConsole"> - <trans-unit id="_msg623"> + <trans-unit id="_msg625"> <source xml:space="preserve">Yes</source> <context-group purpose="location"><context context-type="linenumber">142</context></context-group> </trans-unit> - <trans-unit id="_msg624"> + <trans-unit id="_msg626"> <source xml:space="preserve">No</source> <context-group purpose="location"><context context-type="linenumber">142</context></context-group> </trans-unit> - <trans-unit id="_msg625"> + <trans-unit id="_msg627"> <source xml:space="preserve">To</source> <context-group purpose="location"><context context-type="linenumber">142</context></context-group> </trans-unit> - <trans-unit id="_msg626"> + <trans-unit id="_msg628"> <source xml:space="preserve">From</source> <context-group purpose="location"><context context-type="linenumber">142</context></context-group> </trans-unit> - <trans-unit id="_msg627"> + <trans-unit id="_msg629"> <source xml:space="preserve">Ban for</source> <context-group purpose="location"><context context-type="linenumber">143</context></context-group> </trans-unit> - <trans-unit id="_msg628"> + <trans-unit id="_msg630"> <source xml:space="preserve">Never</source> <context-group purpose="location"><context context-type="linenumber">185</context></context-group> </trans-unit> - <trans-unit id="_msg629"> + <trans-unit id="_msg631"> <source xml:space="preserve">Unknown</source> <context-group purpose="location"><context context-type="linenumber">143</context></context-group> </trans-unit> @@ -2922,72 +2930,72 @@ For more information on using this console, type %6. </body></file> <file original="../forms/receivecoinsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="ReceiveCoinsDialog"> - <trans-unit id="_msg630"> + <trans-unit id="_msg632"> <source xml:space="preserve">&Amount:</source> <context-group purpose="location"><context context-type="linenumber">37</context></context-group> </trans-unit> - <trans-unit id="_msg631"> + <trans-unit id="_msg633"> <source xml:space="preserve">&Label:</source> <context-group purpose="location"><context context-type="linenumber">83</context></context-group> </trans-unit> - <trans-unit id="_msg632"> + <trans-unit id="_msg634"> <source xml:space="preserve">&Message:</source> <context-group purpose="location"><context context-type="linenumber">53</context></context-group> </trans-unit> - <trans-unit id="_msg633"> + <trans-unit id="_msg635"> <source xml:space="preserve">An optional message to attach to the payment request, which will be displayed when the request is opened. Note: The message will not be sent with the payment over the Bitcoin network.</source> <context-group purpose="location"><context context-type="linenumber">50</context></context-group> </trans-unit> - <trans-unit id="_msg634"> + <trans-unit id="_msg636"> <source xml:space="preserve">An optional label to associate with the new receiving address.</source> <context-group purpose="location"><context context-type="linenumber">80</context></context-group> </trans-unit> - <trans-unit id="_msg635"> + <trans-unit id="_msg637"> <source xml:space="preserve">Use this form to request payments. All fields are <b>optional</b>.</source> <context-group purpose="location"><context context-type="linenumber">73</context></context-group> </trans-unit> - <trans-unit id="_msg636"> + <trans-unit id="_msg638"> <source xml:space="preserve">An optional amount to request. Leave this empty or zero to not request a specific amount.</source> <context-group purpose="location"><context context-type="linenumber">34</context></context-group> <context-group purpose="location"><context context-type="linenumber">193</context></context-group> </trans-unit> - <trans-unit id="_msg637"> + <trans-unit id="_msg639"> <source xml:space="preserve">An optional label to associate with the new receiving address (used by you to identify an invoice). It is also attached to the payment request.</source> <context-group purpose="location"><context context-type="linenumber">66</context></context-group> </trans-unit> - <trans-unit id="_msg638"> + <trans-unit id="_msg640"> <source xml:space="preserve">An optional message that is attached to the payment request and may be displayed to the sender.</source> <context-group purpose="location"><context context-type="linenumber">96</context></context-group> </trans-unit> - <trans-unit id="_msg639"> + <trans-unit id="_msg641"> <source xml:space="preserve">&Create new receiving address</source> <context-group purpose="location"><context context-type="linenumber">111</context></context-group> </trans-unit> - <trans-unit id="_msg640"> + <trans-unit id="_msg642"> <source xml:space="preserve">Clear all fields of the form.</source> <context-group purpose="location"><context context-type="linenumber">134</context></context-group> </trans-unit> - <trans-unit id="_msg641"> + <trans-unit id="_msg643"> <source xml:space="preserve">Clear</source> <context-group purpose="location"><context context-type="linenumber">137</context></context-group> </trans-unit> - <trans-unit id="_msg642"> + <trans-unit id="_msg644"> <source xml:space="preserve">Requested payments history</source> <context-group purpose="location"><context context-type="linenumber">273</context></context-group> </trans-unit> - <trans-unit id="_msg643"> + <trans-unit id="_msg645"> <source xml:space="preserve">Show the selected request (does the same as double clicking an entry)</source> <context-group purpose="location"><context context-type="linenumber">298</context></context-group> </trans-unit> - <trans-unit id="_msg644"> + <trans-unit id="_msg646"> <source xml:space="preserve">Show</source> <context-group purpose="location"><context context-type="linenumber">301</context></context-group> </trans-unit> - <trans-unit id="_msg645"> + <trans-unit id="_msg647"> <source xml:space="preserve">Remove the selected entries from the list</source> <context-group purpose="location"><context context-type="linenumber">318</context></context-group> </trans-unit> - <trans-unit id="_msg646"> + <trans-unit id="_msg648"> <source xml:space="preserve">Remove</source> <context-group purpose="location"><context context-type="linenumber">321</context></context-group> </trans-unit> @@ -2995,31 +3003,31 @@ For more information on using this console, type %6. </body></file> <file original="../receivecoinsdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="ReceiveCoinsDialog"> - <trans-unit id="_msg647"> + <trans-unit id="_msg649"> <source xml:space="preserve">Copy &URI</source> <context-group purpose="location"><context context-type="linenumber">47</context></context-group> </trans-unit> - <trans-unit id="_msg648"> + <trans-unit id="_msg650"> <source xml:space="preserve">&Copy address</source> <context-group purpose="location"><context context-type="linenumber">48</context></context-group> </trans-unit> - <trans-unit id="_msg649"> + <trans-unit id="_msg651"> <source xml:space="preserve">Copy &label</source> <context-group purpose="location"><context context-type="linenumber">49</context></context-group> </trans-unit> - <trans-unit id="_msg650"> + <trans-unit id="_msg652"> <source xml:space="preserve">Copy &message</source> <context-group purpose="location"><context context-type="linenumber">50</context></context-group> </trans-unit> - <trans-unit id="_msg651"> + <trans-unit id="_msg653"> <source xml:space="preserve">Copy &amount</source> <context-group purpose="location"><context context-type="linenumber">51</context></context-group> </trans-unit> - <trans-unit id="_msg652"> + <trans-unit id="_msg654"> <source xml:space="preserve">Could not unlock wallet.</source> <context-group purpose="location"><context context-type="linenumber">176</context></context-group> </trans-unit> - <trans-unit id="_msg653"> + <trans-unit id="_msg655"> <source xml:space="preserve">Could not generate new %1 address</source> <context-group purpose="location"><context context-type="linenumber">181</context></context-group> </trans-unit> @@ -3027,51 +3035,51 @@ For more information on using this console, type %6. </body></file> <file original="../forms/receiverequestdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="ReceiveRequestDialog"> - <trans-unit id="_msg654"> + <trans-unit id="_msg656"> <source xml:space="preserve">Request payment to …</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg655"> + <trans-unit id="_msg657"> <source xml:space="preserve">Address:</source> <context-group purpose="location"><context context-type="linenumber">90</context></context-group> </trans-unit> - <trans-unit id="_msg656"> + <trans-unit id="_msg658"> <source xml:space="preserve">Amount:</source> <context-group purpose="location"><context context-type="linenumber">119</context></context-group> </trans-unit> - <trans-unit id="_msg657"> + <trans-unit id="_msg659"> <source xml:space="preserve">Label:</source> <context-group purpose="location"><context context-type="linenumber">148</context></context-group> </trans-unit> - <trans-unit id="_msg658"> + <trans-unit id="_msg660"> <source xml:space="preserve">Message:</source> <context-group purpose="location"><context context-type="linenumber">180</context></context-group> </trans-unit> - <trans-unit id="_msg659"> + <trans-unit id="_msg661"> <source xml:space="preserve">Wallet:</source> <context-group purpose="location"><context context-type="linenumber">212</context></context-group> </trans-unit> - <trans-unit id="_msg660"> + <trans-unit id="_msg662"> <source xml:space="preserve">Copy &URI</source> <context-group purpose="location"><context context-type="linenumber">240</context></context-group> </trans-unit> - <trans-unit id="_msg661"> + <trans-unit id="_msg663"> <source xml:space="preserve">Copy &Address</source> <context-group purpose="location"><context context-type="linenumber">250</context></context-group> </trans-unit> - <trans-unit id="_msg662"> + <trans-unit id="_msg664"> <source xml:space="preserve">&Verify</source> <context-group purpose="location"><context context-type="linenumber">260</context></context-group> </trans-unit> - <trans-unit id="_msg663"> + <trans-unit id="_msg665"> <source xml:space="preserve">Verify this address on e.g. a hardware wallet screen</source> <context-group purpose="location"><context context-type="linenumber">263</context></context-group> </trans-unit> - <trans-unit id="_msg664"> + <trans-unit id="_msg666"> <source xml:space="preserve">&Save Image…</source> <context-group purpose="location"><context context-type="linenumber">273</context></context-group> </trans-unit> - <trans-unit id="_msg665"> + <trans-unit id="_msg667"> <source xml:space="preserve">Payment information</source> <context-group purpose="location"><context context-type="linenumber">39</context></context-group> </trans-unit> @@ -3079,7 +3087,7 @@ For more information on using this console, type %6. </body></file> <file original="../receiverequestdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="ReceiveRequestDialog"> - <trans-unit id="_msg666"> + <trans-unit id="_msg668"> <source xml:space="preserve">Request payment to %1</source> <context-group purpose="location"><context context-type="linenumber">49</context></context-group> </trans-unit> @@ -3087,31 +3095,31 @@ For more information on using this console, type %6. </body></file> <file original="../recentrequeststablemodel.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="RecentRequestsTableModel"> - <trans-unit id="_msg667"> + <trans-unit id="_msg669"> <source xml:space="preserve">Date</source> <context-group purpose="location"><context context-type="linenumber">32</context></context-group> </trans-unit> - <trans-unit id="_msg668"> + <trans-unit id="_msg670"> <source xml:space="preserve">Label</source> <context-group purpose="location"><context context-type="linenumber">32</context></context-group> </trans-unit> - <trans-unit id="_msg669"> + <trans-unit id="_msg671"> <source xml:space="preserve">Message</source> <context-group purpose="location"><context context-type="linenumber">32</context></context-group> </trans-unit> - <trans-unit id="_msg670"> + <trans-unit id="_msg672"> <source xml:space="preserve">(no label)</source> <context-group purpose="location"><context context-type="linenumber">70</context></context-group> </trans-unit> - <trans-unit id="_msg671"> + <trans-unit id="_msg673"> <source xml:space="preserve">(no message)</source> <context-group purpose="location"><context context-type="linenumber">79</context></context-group> </trans-unit> - <trans-unit id="_msg672"> + <trans-unit id="_msg674"> <source xml:space="preserve">(no amount requested)</source> <context-group purpose="location"><context context-type="linenumber">87</context></context-group> </trans-unit> - <trans-unit id="_msg673"> + <trans-unit id="_msg675"> <source xml:space="preserve">Requested</source> <context-group purpose="location"><context context-type="linenumber">130</context></context-group> </trans-unit> @@ -3119,154 +3127,154 @@ For more information on using this console, type %6. </body></file> <file original="../forms/sendcoinsdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="SendCoinsDialog"> - <trans-unit id="_msg674"> + <trans-unit id="_msg676"> <source xml:space="preserve">Send Coins</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> - <context-group purpose="location"><context context-type="sourcefile">../sendcoinsdialog.cpp</context><context context-type="linenumber">759</context></context-group> + <context-group purpose="location"><context context-type="sourcefile">../sendcoinsdialog.cpp</context><context context-type="linenumber">757</context></context-group> </trans-unit> - <trans-unit id="_msg675"> + <trans-unit id="_msg677"> <source xml:space="preserve">Coin Control Features</source> <context-group purpose="location"><context context-type="linenumber">90</context></context-group> </trans-unit> - <trans-unit id="_msg676"> + <trans-unit id="_msg678"> <source xml:space="preserve">automatically selected</source> <context-group purpose="location"><context context-type="linenumber">120</context></context-group> </trans-unit> - <trans-unit id="_msg677"> + <trans-unit id="_msg679"> <source xml:space="preserve">Insufficient funds!</source> <context-group purpose="location"><context context-type="linenumber">139</context></context-group> </trans-unit> - <trans-unit id="_msg678"> + <trans-unit id="_msg680"> <source xml:space="preserve">Quantity:</source> <context-group purpose="location"><context context-type="linenumber">228</context></context-group> </trans-unit> - <trans-unit id="_msg679"> + <trans-unit id="_msg681"> <source xml:space="preserve">Bytes:</source> <context-group purpose="location"><context context-type="linenumber">263</context></context-group> </trans-unit> - <trans-unit id="_msg680"> + <trans-unit id="_msg682"> <source xml:space="preserve">Amount:</source> <context-group purpose="location"><context context-type="linenumber">311</context></context-group> </trans-unit> - <trans-unit id="_msg681"> + <trans-unit id="_msg683"> <source xml:space="preserve">Fee:</source> <context-group purpose="location"><context context-type="linenumber">391</context></context-group> </trans-unit> - <trans-unit id="_msg682"> + <trans-unit id="_msg684"> <source xml:space="preserve">After Fee:</source> <context-group purpose="location"><context context-type="linenumber">442</context></context-group> </trans-unit> - <trans-unit id="_msg683"> + <trans-unit id="_msg685"> <source xml:space="preserve">Change:</source> <context-group purpose="location"><context context-type="linenumber">474</context></context-group> </trans-unit> - <trans-unit id="_msg684"> + <trans-unit id="_msg686"> <source xml:space="preserve">If this is activated, but the change address is empty or invalid, change will be sent to a newly generated address.</source> <context-group purpose="location"><context context-type="linenumber">518</context></context-group> </trans-unit> - <trans-unit id="_msg685"> + <trans-unit id="_msg687"> <source xml:space="preserve">Custom change address</source> <context-group purpose="location"><context context-type="linenumber">521</context></context-group> </trans-unit> - <trans-unit id="_msg686"> + <trans-unit id="_msg688"> <source xml:space="preserve">Transaction Fee:</source> <context-group purpose="location"><context context-type="linenumber">727</context></context-group> </trans-unit> - <trans-unit id="_msg687"> + <trans-unit id="_msg689"> <source xml:space="preserve">Using the fallbackfee can result in sending a transaction that will take several hours or days (or never) to confirm. Consider choosing your fee manually or wait until you have validated the complete chain.</source> <context-group purpose="location"><context context-type="linenumber">765</context></context-group> </trans-unit> - <trans-unit id="_msg688"> + <trans-unit id="_msg690"> <source xml:space="preserve">Warning: Fee estimation is currently not possible.</source> <context-group purpose="location"><context context-type="linenumber">774</context></context-group> </trans-unit> - <trans-unit id="_msg689"> + <trans-unit id="_msg691"> <source xml:space="preserve">per kilobyte</source> <context-group purpose="location"><context context-type="linenumber">856</context></context-group> </trans-unit> - <trans-unit id="_msg690"> + <trans-unit id="_msg692"> <source xml:space="preserve">Hide</source> <context-group purpose="location"><context context-type="linenumber">803</context></context-group> </trans-unit> - <trans-unit id="_msg691"> + <trans-unit id="_msg693"> <source xml:space="preserve">Recommended:</source> <context-group purpose="location"><context context-type="linenumber">915</context></context-group> </trans-unit> - <trans-unit id="_msg692"> + <trans-unit id="_msg694"> <source xml:space="preserve">Custom:</source> <context-group purpose="location"><context context-type="linenumber">945</context></context-group> </trans-unit> - <trans-unit id="_msg693"> + <trans-unit id="_msg695"> <source xml:space="preserve">Send to multiple recipients at once</source> <context-group purpose="location"><context context-type="linenumber">1160</context></context-group> </trans-unit> - <trans-unit id="_msg694"> + <trans-unit id="_msg696"> <source xml:space="preserve">Add &Recipient</source> <context-group purpose="location"><context context-type="linenumber">1163</context></context-group> </trans-unit> - <trans-unit id="_msg695"> + <trans-unit id="_msg697"> <source xml:space="preserve">Clear all fields of the form.</source> <context-group purpose="location"><context context-type="linenumber">1143</context></context-group> </trans-unit> - <trans-unit id="_msg696"> + <trans-unit id="_msg698"> <source xml:space="preserve">Inputs…</source> <context-group purpose="location"><context context-type="linenumber">110</context></context-group> </trans-unit> - <trans-unit id="_msg697"> + <trans-unit id="_msg699"> <source xml:space="preserve">Dust:</source> <context-group purpose="location"><context context-type="linenumber">343</context></context-group> </trans-unit> - <trans-unit id="_msg698"> + <trans-unit id="_msg700"> <source xml:space="preserve">Choose…</source> <context-group purpose="location"><context context-type="linenumber">741</context></context-group> </trans-unit> - <trans-unit id="_msg699"> + <trans-unit id="_msg701"> <source xml:space="preserve">Hide transaction fee settings</source> <context-group purpose="location"><context context-type="linenumber">800</context></context-group> </trans-unit> - <trans-unit id="_msg700"> + <trans-unit id="_msg702"> <source xml:space="preserve">Specify a custom fee per kB (1,000 bytes) of the transaction's virtual size. Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 satoshis per kvB" for a transaction size of 500 virtual bytes (half of 1 kvB) would ultimately yield a fee of only 50 satoshis.</source> <context-group purpose="location"><context context-type="linenumber">851</context></context-group> </trans-unit> - <trans-unit id="_msg701"> + <trans-unit id="_msg703"> <source xml:space="preserve">When there is less transaction volume than space in the blocks, miners as well as relaying nodes may enforce a minimum fee. Paying only this minimum fee is just fine, but be aware that this can result in a never confirming transaction once there is more demand for bitcoin transactions than the network can process.</source> <context-group purpose="location"><context context-type="linenumber">886</context></context-group> </trans-unit> - <trans-unit id="_msg702"> + <trans-unit id="_msg704"> <source xml:space="preserve">A too low fee might result in a never confirming transaction (read the tooltip)</source> <context-group purpose="location"><context context-type="linenumber">889</context></context-group> </trans-unit> - <trans-unit id="_msg703"> + <trans-unit id="_msg705"> <source xml:space="preserve">(Smart fee not initialized yet. This usually takes a few blocks…)</source> <context-group purpose="location"><context context-type="linenumber">994</context></context-group> </trans-unit> - <trans-unit id="_msg704"> + <trans-unit id="_msg706"> <source xml:space="preserve">Confirmation time target:</source> <context-group purpose="location"><context context-type="linenumber">1020</context></context-group> </trans-unit> - <trans-unit id="_msg705"> + <trans-unit id="_msg707"> <source xml:space="preserve">Enable Replace-By-Fee</source> <context-group purpose="location"><context context-type="linenumber">1078</context></context-group> </trans-unit> - <trans-unit id="_msg706"> + <trans-unit id="_msg708"> <source xml:space="preserve">With Replace-By-Fee (BIP-125) you can increase a transaction's fee after it is sent. Without this, a higher fee may be recommended to compensate for increased transaction delay risk.</source> <context-group purpose="location"><context context-type="linenumber">1081</context></context-group> </trans-unit> - <trans-unit id="_msg707"> + <trans-unit id="_msg709"> <source xml:space="preserve">Clear &All</source> <context-group purpose="location"><context context-type="linenumber">1146</context></context-group> </trans-unit> - <trans-unit id="_msg708"> + <trans-unit id="_msg710"> <source xml:space="preserve">Balance:</source> <context-group purpose="location"><context context-type="linenumber">1201</context></context-group> </trans-unit> - <trans-unit id="_msg709"> + <trans-unit id="_msg711"> <source xml:space="preserve">Confirm the send action</source> <context-group purpose="location"><context context-type="linenumber">1117</context></context-group> </trans-unit> - <trans-unit id="_msg710"> + <trans-unit id="_msg712"> <source xml:space="preserve">S&end</source> <context-group purpose="location"><context context-type="linenumber">1120</context></context-group> </trans-unit> @@ -3274,278 +3282,278 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../sendcoinsdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="SendCoinsDialog"> - <trans-unit id="_msg711"> + <trans-unit id="_msg713"> <source xml:space="preserve">Copy quantity</source> <context-group purpose="location"><context context-type="linenumber">99</context></context-group> </trans-unit> - <trans-unit id="_msg712"> + <trans-unit id="_msg714"> <source xml:space="preserve">Copy amount</source> <context-group purpose="location"><context context-type="linenumber">100</context></context-group> </trans-unit> - <trans-unit id="_msg713"> + <trans-unit id="_msg715"> <source xml:space="preserve">Copy fee</source> <context-group purpose="location"><context context-type="linenumber">101</context></context-group> </trans-unit> - <trans-unit id="_msg714"> + <trans-unit id="_msg716"> <source xml:space="preserve">Copy after fee</source> <context-group purpose="location"><context context-type="linenumber">102</context></context-group> </trans-unit> - <trans-unit id="_msg715"> + <trans-unit id="_msg717"> <source xml:space="preserve">Copy bytes</source> <context-group purpose="location"><context context-type="linenumber">103</context></context-group> </trans-unit> - <trans-unit id="_msg716"> + <trans-unit id="_msg718"> <source xml:space="preserve">Copy dust</source> <context-group purpose="location"><context context-type="linenumber">104</context></context-group> </trans-unit> - <trans-unit id="_msg717"> + <trans-unit id="_msg719"> <source xml:space="preserve">Copy change</source> <context-group purpose="location"><context context-type="linenumber">105</context></context-group> </trans-unit> - <trans-unit id="_msg718"> + <trans-unit id="_msg720"> <source xml:space="preserve">%1 (%2 blocks)</source> - <context-group purpose="location"><context context-type="linenumber">181</context></context-group> + <context-group purpose="location"><context context-type="linenumber">179</context></context-group> </trans-unit> - <trans-unit id="_msg719"> + <trans-unit id="_msg721"> <source xml:space="preserve">Sign on device</source> - <context-group purpose="location"><context context-type="linenumber">211</context></context-group> + <context-group purpose="location"><context context-type="linenumber">209</context></context-group> <note annotates="source" from="developer">"device" usually means a hardware wallet.</note> </trans-unit> - <trans-unit id="_msg720"> + <trans-unit id="_msg722"> <source xml:space="preserve">Connect your hardware wallet first.</source> - <context-group purpose="location"><context context-type="linenumber">214</context></context-group> + <context-group purpose="location"><context context-type="linenumber">212</context></context-group> </trans-unit> - <trans-unit id="_msg721"> + <trans-unit id="_msg723"> <source xml:space="preserve">Set external signer script path in Options -> Wallet</source> - <context-group purpose="location"><context context-type="linenumber">218</context></context-group> + <context-group purpose="location"><context context-type="linenumber">216</context></context-group> <note annotates="source" from="developer">"External signer" means using devices such as hardware wallets.</note> </trans-unit> - <trans-unit id="_msg722"> + <trans-unit id="_msg724"> <source xml:space="preserve">Cr&eate Unsigned</source> - <context-group purpose="location"><context context-type="linenumber">221</context></context-group> + <context-group purpose="location"><context context-type="linenumber">219</context></context-group> </trans-unit> - <trans-unit id="_msg723"> + <trans-unit id="_msg725"> <source xml:space="preserve">Creates a Partially Signed Bitcoin Transaction (PSBT) for use with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.</source> - <context-group purpose="location"><context context-type="linenumber">222</context></context-group> + <context-group purpose="location"><context context-type="linenumber">220</context></context-group> </trans-unit> - <trans-unit id="_msg724"> + <trans-unit id="_msg726"> <source xml:space="preserve"> from wallet '%1'</source> - <context-group purpose="location"><context context-type="linenumber">312</context></context-group> + <context-group purpose="location"><context context-type="linenumber">310</context></context-group> </trans-unit> - <trans-unit id="_msg725"> + <trans-unit id="_msg727"> <source xml:space="preserve">%1 to '%2'</source> - <context-group purpose="location"><context context-type="linenumber">323</context></context-group> + <context-group purpose="location"><context context-type="linenumber">321</context></context-group> </trans-unit> - <trans-unit id="_msg726"> + <trans-unit id="_msg728"> <source xml:space="preserve">%1 to %2</source> - <context-group purpose="location"><context context-type="linenumber">328</context></context-group> + <context-group purpose="location"><context context-type="linenumber">326</context></context-group> </trans-unit> - <trans-unit id="_msg727"> + <trans-unit id="_msg729"> <source xml:space="preserve">To review recipient list click "Show Details…"</source> - <context-group purpose="location"><context context-type="linenumber">394</context></context-group> + <context-group purpose="location"><context context-type="linenumber">392</context></context-group> </trans-unit> - <trans-unit id="_msg728"> + <trans-unit id="_msg730"> <source xml:space="preserve">Sign failed</source> - <context-group purpose="location"><context context-type="linenumber">454</context></context-group> + <context-group purpose="location"><context context-type="linenumber">452</context></context-group> </trans-unit> - <trans-unit id="_msg729"> + <trans-unit id="_msg731"> <source xml:space="preserve">External signer not found</source> - <context-group purpose="location"><context context-type="linenumber">459</context></context-group> + <context-group purpose="location"><context context-type="linenumber">457</context></context-group> <note annotates="source" from="developer">"External signer" means using devices such as hardware wallets.</note> </trans-unit> - <trans-unit id="_msg730"> + <trans-unit id="_msg732"> <source xml:space="preserve">External signer failure</source> - <context-group purpose="location"><context context-type="linenumber">464</context></context-group> + <context-group purpose="location"><context context-type="linenumber">462</context></context-group> <note annotates="source" from="developer">"External signer" means using devices such as hardware wallets.</note> </trans-unit> - <trans-unit id="_msg731"> + <trans-unit id="_msg733"> <source xml:space="preserve">Save Transaction Data</source> - <context-group purpose="location"><context context-type="linenumber">430</context></context-group> + <context-group purpose="location"><context context-type="linenumber">428</context></context-group> </trans-unit> - <trans-unit id="_msg732"> + <trans-unit id="_msg734"> <source xml:space="preserve">Partially Signed Transaction (Binary)</source> - <context-group purpose="location"><context context-type="linenumber">432</context></context-group> + <context-group purpose="location"><context context-type="linenumber">430</context></context-group> <note annotates="source" from="developer">Expanded name of the binary PSBT file format. See: BIP 174.</note> </trans-unit> - <trans-unit id="_msg733"> + <trans-unit id="_msg735"> <source xml:space="preserve">PSBT saved</source> - <context-group purpose="location"><context context-type="linenumber">439</context></context-group> + <context-group purpose="location"><context context-type="linenumber">437</context></context-group> </trans-unit> - <trans-unit id="_msg734"> + <trans-unit id="_msg736"> <source xml:space="preserve">External balance:</source> - <context-group purpose="location"><context context-type="linenumber">705</context></context-group> + <context-group purpose="location"><context context-type="linenumber">703</context></context-group> </trans-unit> - <trans-unit id="_msg735"> + <trans-unit id="_msg737"> <source xml:space="preserve">or</source> - <context-group purpose="location"><context context-type="linenumber">390</context></context-group> + <context-group purpose="location"><context context-type="linenumber">388</context></context-group> </trans-unit> - <trans-unit id="_msg736"> + <trans-unit id="_msg738"> <source xml:space="preserve">You can increase the fee later (signals Replace-By-Fee, BIP-125).</source> - <context-group purpose="location"><context context-type="linenumber">372</context></context-group> + <context-group purpose="location"><context context-type="linenumber">370</context></context-group> </trans-unit> - <trans-unit id="_msg737"> + <trans-unit id="_msg739"> <source xml:space="preserve">Please, review your transaction proposal. This will produce a Partially Signed Bitcoin Transaction (PSBT) which you can save or copy and then sign with e.g. an offline %1 wallet, or a PSBT-compatible hardware wallet.</source> - <context-group purpose="location"><context context-type="linenumber">342</context></context-group> + <context-group purpose="location"><context context-type="linenumber">340</context></context-group> <note annotates="source" from="developer">Text to inform a user attempting to create a transaction of their current options. At this stage, a user can only create a PSBT. This string is displayed when private keys are disabled and an external signer is not available.</note> </trans-unit> - <trans-unit id="_msg738"> + <trans-unit id="_msg740"> <source xml:space="preserve">Do you want to create this transaction?</source> - <context-group purpose="location"><context context-type="linenumber">336</context></context-group> + <context-group purpose="location"><context context-type="linenumber">334</context></context-group> <note annotates="source" from="developer">Message displayed when attempting to create a transaction. Cautionary text to prompt the user to verify that the displayed transaction details represent the transaction the user intends to create.</note> </trans-unit> - <trans-unit id="_msg739"> + <trans-unit id="_msg741"> <source xml:space="preserve">Please, review your transaction. You can create and send this transaction or create a Partially Signed Bitcoin Transaction (PSBT), which you can save or copy and then sign with, e.g., an offline %1 wallet, or a PSBT-compatible hardware wallet.</source> - <context-group purpose="location"><context context-type="linenumber">347</context></context-group> + <context-group purpose="location"><context context-type="linenumber">345</context></context-group> <note annotates="source" from="developer">Text to inform a user attempting to create a transaction of their current options. At this stage, a user can send their transaction or create a PSBT. This string is displayed when both private keys and PSBT controls are enabled.</note> </trans-unit> - <trans-unit id="_msg740"> + <trans-unit id="_msg742"> <source xml:space="preserve">Please, review your transaction.</source> - <context-group purpose="location"><context context-type="linenumber">350</context></context-group> + <context-group purpose="location"><context context-type="linenumber">348</context></context-group> <note annotates="source" from="developer">Text to prompt a user to review the details of the transaction they are attempting to send.</note> </trans-unit> - <trans-unit id="_msg741"> + <trans-unit id="_msg743"> <source xml:space="preserve">Transaction fee</source> - <context-group purpose="location"><context context-type="linenumber">358</context></context-group> + <context-group purpose="location"><context context-type="linenumber">356</context></context-group> </trans-unit> - <trans-unit id="_msg742"> + <trans-unit id="_msg744"> <source xml:space="preserve">Not signalling Replace-By-Fee, BIP-125.</source> - <context-group purpose="location"><context context-type="linenumber">374</context></context-group> + <context-group purpose="location"><context context-type="linenumber">372</context></context-group> </trans-unit> - <trans-unit id="_msg743"> + <trans-unit id="_msg745"> <source xml:space="preserve">Total Amount</source> - <context-group purpose="location"><context context-type="linenumber">387</context></context-group> + <context-group purpose="location"><context context-type="linenumber">385</context></context-group> </trans-unit> - <trans-unit id="_msg744"> + <trans-unit id="_msg746"> <source xml:space="preserve">Confirm send coins</source> - <context-group purpose="location"><context context-type="linenumber">486</context></context-group> + <context-group purpose="location"><context context-type="linenumber">484</context></context-group> </trans-unit> - <trans-unit id="_msg745"> + <trans-unit id="_msg747"> <source xml:space="preserve">Watch-only balance:</source> - <context-group purpose="location"><context context-type="linenumber">708</context></context-group> + <context-group purpose="location"><context context-type="linenumber">706</context></context-group> </trans-unit> - <trans-unit id="_msg746"> + <trans-unit id="_msg748"> <source xml:space="preserve">The recipient address is not valid. Please recheck.</source> - <context-group purpose="location"><context context-type="linenumber">732</context></context-group> + <context-group purpose="location"><context context-type="linenumber">730</context></context-group> </trans-unit> - <trans-unit id="_msg747"> + <trans-unit id="_msg749"> <source xml:space="preserve">The amount to pay must be larger than 0.</source> - <context-group purpose="location"><context context-type="linenumber">735</context></context-group> + <context-group purpose="location"><context context-type="linenumber">733</context></context-group> </trans-unit> - <trans-unit id="_msg748"> + <trans-unit id="_msg750"> <source xml:space="preserve">The amount exceeds your balance.</source> - <context-group purpose="location"><context context-type="linenumber">738</context></context-group> + <context-group purpose="location"><context context-type="linenumber">736</context></context-group> </trans-unit> - <trans-unit id="_msg749"> + <trans-unit id="_msg751"> <source xml:space="preserve">The total exceeds your balance when the %1 transaction fee is included.</source> - <context-group purpose="location"><context context-type="linenumber">741</context></context-group> + <context-group purpose="location"><context context-type="linenumber">739</context></context-group> </trans-unit> - <trans-unit id="_msg750"> + <trans-unit id="_msg752"> <source xml:space="preserve">Duplicate address found: addresses should only be used once each.</source> - <context-group purpose="location"><context context-type="linenumber">744</context></context-group> + <context-group purpose="location"><context context-type="linenumber">742</context></context-group> </trans-unit> - <trans-unit id="_msg751"> + <trans-unit id="_msg753"> <source xml:space="preserve">Transaction creation failed!</source> - <context-group purpose="location"><context context-type="linenumber">747</context></context-group> + <context-group purpose="location"><context context-type="linenumber">745</context></context-group> </trans-unit> - <trans-unit id="_msg752"> + <trans-unit id="_msg754"> <source xml:space="preserve">A fee higher than %1 is considered an absurdly high fee.</source> - <context-group purpose="location"><context context-type="linenumber">751</context></context-group> + <context-group purpose="location"><context context-type="linenumber">749</context></context-group> </trans-unit> <group restype="x-gettext-plurals"> - <context-group purpose="location"><context context-type="linenumber">874</context></context-group> - <trans-unit id="_msg753[0]"> + <context-group purpose="location"><context context-type="linenumber">872</context></context-group> + <trans-unit id="_msg755[0]"> <source xml:space="preserve">Estimated to begin confirmation within %n block(s).</source> </trans-unit> - <trans-unit id="_msg753[1]"> + <trans-unit id="_msg755[1]"> <source xml:space="preserve">Estimated to begin confirmation within %n block(s).</source> </trans-unit> </group> - <trans-unit id="_msg754"> + <trans-unit id="_msg756"> <source xml:space="preserve">Warning: Invalid Bitcoin address</source> - <context-group purpose="location"><context context-type="linenumber">975</context></context-group> + <context-group purpose="location"><context context-type="linenumber">973</context></context-group> </trans-unit> - <trans-unit id="_msg755"> + <trans-unit id="_msg757"> <source xml:space="preserve">Warning: Unknown change address</source> - <context-group purpose="location"><context context-type="linenumber">980</context></context-group> + <context-group purpose="location"><context context-type="linenumber">978</context></context-group> </trans-unit> - <trans-unit id="_msg756"> + <trans-unit id="_msg758"> <source xml:space="preserve">Confirm custom change address</source> - <context-group purpose="location"><context context-type="linenumber">983</context></context-group> + <context-group purpose="location"><context context-type="linenumber">981</context></context-group> </trans-unit> - <trans-unit id="_msg757"> + <trans-unit id="_msg759"> <source xml:space="preserve">The address you selected for change is not part of this wallet. Any or all funds in your wallet may be sent to this address. Are you sure?</source> - <context-group purpose="location"><context context-type="linenumber">983</context></context-group> + <context-group purpose="location"><context context-type="linenumber">981</context></context-group> </trans-unit> - <trans-unit id="_msg758"> + <trans-unit id="_msg760"> <source xml:space="preserve">(no label)</source> - <context-group purpose="location"><context context-type="linenumber">1004</context></context-group> + <context-group purpose="location"><context context-type="linenumber">1002</context></context-group> </trans-unit> </group> </body></file> <file original="../forms/sendcoinsentry.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="SendCoinsEntry"> - <trans-unit id="_msg759"> + <trans-unit id="_msg761"> <source xml:space="preserve">A&mount:</source> <context-group purpose="location"><context context-type="linenumber">151</context></context-group> </trans-unit> - <trans-unit id="_msg760"> + <trans-unit id="_msg762"> <source xml:space="preserve">Pay &To:</source> <context-group purpose="location"><context context-type="linenumber">35</context></context-group> </trans-unit> - <trans-unit id="_msg761"> + <trans-unit id="_msg763"> <source xml:space="preserve">&Label:</source> <context-group purpose="location"><context context-type="linenumber">128</context></context-group> </trans-unit> - <trans-unit id="_msg762"> + <trans-unit id="_msg764"> <source xml:space="preserve">Choose previously used address</source> <context-group purpose="location"><context context-type="linenumber">60</context></context-group> </trans-unit> - <trans-unit id="_msg763"> + <trans-unit id="_msg765"> <source xml:space="preserve">The Bitcoin address to send the payment to</source> <context-group purpose="location"><context context-type="linenumber">53</context></context-group> </trans-unit> - <trans-unit id="_msg764"> + <trans-unit id="_msg766"> <source xml:space="preserve">Alt+A</source> <context-group purpose="location"><context context-type="linenumber">76</context></context-group> </trans-unit> - <trans-unit id="_msg765"> + <trans-unit id="_msg767"> <source xml:space="preserve">Paste address from clipboard</source> <context-group purpose="location"><context context-type="linenumber">83</context></context-group> </trans-unit> - <trans-unit id="_msg766"> + <trans-unit id="_msg768"> <source xml:space="preserve">Alt+P</source> <context-group purpose="location"><context context-type="linenumber">99</context></context-group> </trans-unit> - <trans-unit id="_msg767"> + <trans-unit id="_msg769"> <source xml:space="preserve">Remove this entry</source> <context-group purpose="location"><context context-type="linenumber">106</context></context-group> </trans-unit> - <trans-unit id="_msg768"> + <trans-unit id="_msg770"> <source xml:space="preserve">The amount to send in the selected unit</source> <context-group purpose="location"><context context-type="linenumber">166</context></context-group> </trans-unit> - <trans-unit id="_msg769"> + <trans-unit id="_msg771"> <source xml:space="preserve">The fee will be deducted from the amount being sent. The recipient will receive less bitcoins than you enter in the amount field. If multiple recipients are selected, the fee is split equally.</source> <context-group purpose="location"><context context-type="linenumber">173</context></context-group> </trans-unit> - <trans-unit id="_msg770"> + <trans-unit id="_msg772"> <source xml:space="preserve">S&ubtract fee from amount</source> <context-group purpose="location"><context context-type="linenumber">176</context></context-group> </trans-unit> - <trans-unit id="_msg771"> + <trans-unit id="_msg773"> <source xml:space="preserve">Use available balance</source> <context-group purpose="location"><context context-type="linenumber">183</context></context-group> </trans-unit> - <trans-unit id="_msg772"> + <trans-unit id="_msg774"> <source xml:space="preserve">Message:</source> <context-group purpose="location"><context context-type="linenumber">192</context></context-group> </trans-unit> - <trans-unit id="_msg773"> + <trans-unit id="_msg775"> <source xml:space="preserve">Enter a label for this address to add it to the list of used addresses</source> <context-group purpose="location"><context context-type="linenumber">141</context></context-group> <context-group purpose="location"><context context-type="linenumber">144</context></context-group> </trans-unit> - <trans-unit id="_msg774"> + <trans-unit id="_msg776"> <source xml:space="preserve">A message that was attached to the bitcoin: URI which will be stored with the transaction for your reference. Note: This message will not be sent over the Bitcoin network.</source> <context-group purpose="location"><context context-type="linenumber">202</context></context-group> </trans-unit> @@ -3553,11 +3561,11 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../sendcoinsdialog.h" datatype="c" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="SendConfirmationDialog"> - <trans-unit id="_msg775"> + <trans-unit id="_msg777"> <source xml:space="preserve">Send</source> <context-group purpose="location"><context context-type="linenumber">144</context></context-group> </trans-unit> - <trans-unit id="_msg776"> + <trans-unit id="_msg778"> <source xml:space="preserve">Create Unsigned</source> <context-group purpose="location"><context context-type="linenumber">146</context></context-group> </trans-unit> @@ -3565,105 +3573,105 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../forms/signverifymessagedialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="SignVerifyMessageDialog"> - <trans-unit id="_msg777"> + <trans-unit id="_msg779"> <source xml:space="preserve">Signatures - Sign / Verify a Message</source> <context-group purpose="location"><context context-type="linenumber">14</context></context-group> </trans-unit> - <trans-unit id="_msg778"> + <trans-unit id="_msg780"> <source xml:space="preserve">&Sign Message</source> <context-group purpose="location"><context context-type="linenumber">27</context></context-group> </trans-unit> - <trans-unit id="_msg779"> + <trans-unit id="_msg781"> <source xml:space="preserve">You can sign messages/agreements with your addresses to prove you can receive bitcoins sent to them. Be careful not to sign anything vague or random, as phishing attacks may try to trick you into signing your identity over to them. Only sign fully-detailed statements you agree to.</source> <context-group purpose="location"><context context-type="linenumber">33</context></context-group> </trans-unit> - <trans-unit id="_msg780"> + <trans-unit id="_msg782"> <source xml:space="preserve">The Bitcoin address to sign the message with</source> <context-group purpose="location"><context context-type="linenumber">51</context></context-group> </trans-unit> - <trans-unit id="_msg781"> + <trans-unit id="_msg783"> <source xml:space="preserve">Choose previously used address</source> <context-group purpose="location"><context context-type="linenumber">58</context></context-group> <context-group purpose="location"><context context-type="linenumber">274</context></context-group> </trans-unit> - <trans-unit id="_msg782"> + <trans-unit id="_msg784"> <source xml:space="preserve">Alt+A</source> <context-group purpose="location"><context context-type="linenumber">68</context></context-group> <context-group purpose="location"><context context-type="linenumber">284</context></context-group> </trans-unit> - <trans-unit id="_msg783"> + <trans-unit id="_msg785"> <source xml:space="preserve">Paste address from clipboard</source> <context-group purpose="location"><context context-type="linenumber">78</context></context-group> </trans-unit> - <trans-unit id="_msg784"> + <trans-unit id="_msg786"> <source xml:space="preserve">Alt+P</source> <context-group purpose="location"><context context-type="linenumber">88</context></context-group> </trans-unit> - <trans-unit id="_msg785"> + <trans-unit id="_msg787"> <source xml:space="preserve">Enter the message you want to sign here</source> <context-group purpose="location"><context context-type="linenumber">100</context></context-group> <context-group purpose="location"><context context-type="linenumber">103</context></context-group> </trans-unit> - <trans-unit id="_msg786"> + <trans-unit id="_msg788"> <source xml:space="preserve">Signature</source> <context-group purpose="location"><context context-type="linenumber">110</context></context-group> </trans-unit> - <trans-unit id="_msg787"> + <trans-unit id="_msg789"> <source xml:space="preserve">Copy the current signature to the system clipboard</source> <context-group purpose="location"><context context-type="linenumber">140</context></context-group> </trans-unit> - <trans-unit id="_msg788"> + <trans-unit id="_msg790"> <source xml:space="preserve">Sign the message to prove you own this Bitcoin address</source> <context-group purpose="location"><context context-type="linenumber">161</context></context-group> </trans-unit> - <trans-unit id="_msg789"> + <trans-unit id="_msg791"> <source xml:space="preserve">Sign &Message</source> <context-group purpose="location"><context context-type="linenumber">164</context></context-group> </trans-unit> - <trans-unit id="_msg790"> + <trans-unit id="_msg792"> <source xml:space="preserve">Reset all sign message fields</source> <context-group purpose="location"><context context-type="linenumber">178</context></context-group> </trans-unit> - <trans-unit id="_msg791"> + <trans-unit id="_msg793"> <source xml:space="preserve">Clear &All</source> <context-group purpose="location"><context context-type="linenumber">181</context></context-group> <context-group purpose="location"><context context-type="linenumber">338</context></context-group> </trans-unit> - <trans-unit id="_msg792"> + <trans-unit id="_msg794"> <source xml:space="preserve">&Verify Message</source> <context-group purpose="location"><context context-type="linenumber">240</context></context-group> </trans-unit> - <trans-unit id="_msg793"> + <trans-unit id="_msg795"> <source xml:space="preserve">Enter the receiver's address, message (ensure you copy line breaks, spaces, tabs, etc. exactly) and signature below to verify the message. Be careful not to read more into the signature than what is in the signed message itself, to avoid being tricked by a man-in-the-middle attack. Note that this only proves the signing party receives with the address, it cannot prove sendership of any transaction!</source> <context-group purpose="location"><context context-type="linenumber">246</context></context-group> </trans-unit> - <trans-unit id="_msg794"> + <trans-unit id="_msg796"> <source xml:space="preserve">The Bitcoin address the message was signed with</source> <context-group purpose="location"><context context-type="linenumber">267</context></context-group> </trans-unit> - <trans-unit id="_msg795"> + <trans-unit id="_msg797"> <source xml:space="preserve">The signed message to verify</source> <context-group purpose="location"><context context-type="linenumber">296</context></context-group> <context-group purpose="location"><context context-type="linenumber">299</context></context-group> </trans-unit> - <trans-unit id="_msg796"> + <trans-unit id="_msg798"> <source xml:space="preserve">The signature given when the message was signed</source> <context-group purpose="location"><context context-type="linenumber">306</context></context-group> <context-group purpose="location"><context context-type="linenumber">309</context></context-group> </trans-unit> - <trans-unit id="_msg797"> + <trans-unit id="_msg799"> <source xml:space="preserve">Verify the message to ensure it was signed with the specified Bitcoin address</source> <context-group purpose="location"><context context-type="linenumber">318</context></context-group> </trans-unit> - <trans-unit id="_msg798"> + <trans-unit id="_msg800"> <source xml:space="preserve">Verify &Message</source> <context-group purpose="location"><context context-type="linenumber">321</context></context-group> </trans-unit> - <trans-unit id="_msg799"> + <trans-unit id="_msg801"> <source xml:space="preserve">Reset all verify message fields</source> <context-group purpose="location"><context context-type="linenumber">335</context></context-group> </trans-unit> - <trans-unit id="_msg800"> + <trans-unit id="_msg802"> <source xml:space="preserve">Click "Sign Message" to generate signature</source> <context-group purpose="location"><context context-type="linenumber">125</context></context-group> </trans-unit> @@ -3671,61 +3679,61 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../signverifymessagedialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="SignVerifyMessageDialog"> - <trans-unit id="_msg801"> + <trans-unit id="_msg803"> <source xml:space="preserve">The entered address is invalid.</source> <context-group purpose="location"><context context-type="linenumber">120</context></context-group> <context-group purpose="location"><context context-type="linenumber">219</context></context-group> </trans-unit> - <trans-unit id="_msg802"> + <trans-unit id="_msg804"> <source xml:space="preserve">Please check the address and try again.</source> <context-group purpose="location"><context context-type="linenumber">120</context></context-group> <context-group purpose="location"><context context-type="linenumber">127</context></context-group> <context-group purpose="location"><context context-type="linenumber">220</context></context-group> <context-group purpose="location"><context context-type="linenumber">227</context></context-group> </trans-unit> - <trans-unit id="_msg803"> + <trans-unit id="_msg805"> <source xml:space="preserve">The entered address does not refer to a key.</source> <context-group purpose="location"><context context-type="linenumber">127</context></context-group> <context-group purpose="location"><context context-type="linenumber">226</context></context-group> </trans-unit> - <trans-unit id="_msg804"> + <trans-unit id="_msg806"> <source xml:space="preserve">Wallet unlock was cancelled.</source> <context-group purpose="location"><context context-type="linenumber">135</context></context-group> </trans-unit> - <trans-unit id="_msg805"> + <trans-unit id="_msg807"> <source xml:space="preserve">No error</source> <context-group purpose="location"><context context-type="linenumber">146</context></context-group> </trans-unit> - <trans-unit id="_msg806"> + <trans-unit id="_msg808"> <source xml:space="preserve">Private key for the entered address is not available.</source> <context-group purpose="location"><context context-type="linenumber">149</context></context-group> </trans-unit> - <trans-unit id="_msg807"> + <trans-unit id="_msg809"> <source xml:space="preserve">Message signing failed.</source> <context-group purpose="location"><context context-type="linenumber">152</context></context-group> </trans-unit> - <trans-unit id="_msg808"> + <trans-unit id="_msg810"> <source xml:space="preserve">Message signed.</source> <context-group purpose="location"><context context-type="linenumber">164</context></context-group> </trans-unit> - <trans-unit id="_msg809"> + <trans-unit id="_msg811"> <source xml:space="preserve">The signature could not be decoded.</source> <context-group purpose="location"><context context-type="linenumber">233</context></context-group> </trans-unit> - <trans-unit id="_msg810"> + <trans-unit id="_msg812"> <source xml:space="preserve">Please check the signature and try again.</source> <context-group purpose="location"><context context-type="linenumber">234</context></context-group> <context-group purpose="location"><context context-type="linenumber">241</context></context-group> </trans-unit> - <trans-unit id="_msg811"> + <trans-unit id="_msg813"> <source xml:space="preserve">The signature did not match the message digest.</source> <context-group purpose="location"><context context-type="linenumber">240</context></context-group> </trans-unit> - <trans-unit id="_msg812"> + <trans-unit id="_msg814"> <source xml:space="preserve">Message verification failed.</source> <context-group purpose="location"><context context-type="linenumber">246</context></context-group> </trans-unit> - <trans-unit id="_msg813"> + <trans-unit id="_msg815"> <source xml:space="preserve">Message verified.</source> <context-group purpose="location"><context context-type="linenumber">214</context></context-group> </trans-unit> @@ -3733,11 +3741,11 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../splashscreen.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="SplashScreen"> - <trans-unit id="_msg814"> + <trans-unit id="_msg816"> <source xml:space="preserve">(press q to shutdown and continue later)</source> <context-group purpose="location"><context context-type="linenumber">187</context></context-group> </trans-unit> - <trans-unit id="_msg815"> + <trans-unit id="_msg817"> <source xml:space="preserve">press q to shutdown</source> <context-group purpose="location"><context context-type="linenumber">188</context></context-group> </trans-unit> @@ -3745,7 +3753,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../trafficgraphwidget.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="TrafficGraphWidget"> - <trans-unit id="_msg816"> + <trans-unit id="_msg818"> <source xml:space="preserve">kB/s</source> <context-group purpose="location"><context context-type="linenumber">79</context></context-group> </trans-unit> @@ -3753,82 +3761,82 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../transactiondesc.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="TransactionDesc"> - <trans-unit id="_msg817"> + <trans-unit id="_msg819"> <source xml:space="preserve">conflicted with a transaction with %1 confirmations</source> <context-group purpose="location"><context context-type="linenumber">43</context></context-group> <note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that conflicts with a confirmed transaction.</note> </trans-unit> - <trans-unit id="_msg818"> + <trans-unit id="_msg820"> <source xml:space="preserve">0/unconfirmed, in memory pool</source> <context-group purpose="location"><context context-type="linenumber">50</context></context-group> <note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is in the memory pool.</note> </trans-unit> - <trans-unit id="_msg819"> + <trans-unit id="_msg821"> <source xml:space="preserve">0/unconfirmed, not in memory pool</source> <context-group purpose="location"><context context-type="linenumber">55</context></context-group> <note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an unconfirmed transaction that is not in the memory pool.</note> </trans-unit> - <trans-unit id="_msg820"> + <trans-unit id="_msg822"> <source xml:space="preserve">abandoned</source> <context-group purpose="location"><context context-type="linenumber">61</context></context-group> <note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents an abandoned transaction.</note> </trans-unit> - <trans-unit id="_msg821"> + <trans-unit id="_msg823"> <source xml:space="preserve">%1/unconfirmed</source> <context-group purpose="location"><context context-type="linenumber">69</context></context-group> <note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents a transaction confirmed in at least one block, but less than 6 blocks.</note> </trans-unit> - <trans-unit id="_msg822"> + <trans-unit id="_msg824"> <source xml:space="preserve">%1 confirmations</source> <context-group purpose="location"><context context-type="linenumber">74</context></context-group> <note annotates="source" from="developer">Text explaining the current status of a transaction, shown in the status field of the details window for this transaction. This status represents a transaction confirmed in 6 or more blocks.</note> </trans-unit> - <trans-unit id="_msg823"> + <trans-unit id="_msg825"> <source xml:space="preserve">Status</source> <context-group purpose="location"><context context-type="linenumber">124</context></context-group> </trans-unit> - <trans-unit id="_msg824"> + <trans-unit id="_msg826"> <source xml:space="preserve">Date</source> <context-group purpose="location"><context context-type="linenumber">127</context></context-group> </trans-unit> - <trans-unit id="_msg825"> + <trans-unit id="_msg827"> <source xml:space="preserve">Source</source> <context-group purpose="location"><context context-type="linenumber">134</context></context-group> </trans-unit> - <trans-unit id="_msg826"> + <trans-unit id="_msg828"> <source xml:space="preserve">Generated</source> <context-group purpose="location"><context context-type="linenumber">134</context></context-group> </trans-unit> - <trans-unit id="_msg827"> + <trans-unit id="_msg829"> <source xml:space="preserve">From</source> <context-group purpose="location"><context context-type="linenumber">139</context></context-group> <context-group purpose="location"><context context-type="linenumber">153</context></context-group> <context-group purpose="location"><context context-type="linenumber">225</context></context-group> </trans-unit> - <trans-unit id="_msg828"> + <trans-unit id="_msg830"> <source xml:space="preserve">unknown</source> <context-group purpose="location"><context context-type="linenumber">153</context></context-group> </trans-unit> - <trans-unit id="_msg829"> + <trans-unit id="_msg831"> <source xml:space="preserve">To</source> <context-group purpose="location"><context context-type="linenumber">154</context></context-group> <context-group purpose="location"><context context-type="linenumber">174</context></context-group> <context-group purpose="location"><context context-type="linenumber">244</context></context-group> </trans-unit> - <trans-unit id="_msg830"> + <trans-unit id="_msg832"> <source xml:space="preserve">own address</source> <context-group purpose="location"><context context-type="linenumber">156</context></context-group> </trans-unit> - <trans-unit id="_msg831"> + <trans-unit id="_msg833"> <source xml:space="preserve">watch-only</source> <context-group purpose="location"><context context-type="linenumber">156</context></context-group> <context-group purpose="location"><context context-type="linenumber">225</context></context-group> </trans-unit> - <trans-unit id="_msg832"> + <trans-unit id="_msg834"> <source xml:space="preserve">label</source> <context-group purpose="location"><context context-type="linenumber">158</context></context-group> </trans-unit> - <trans-unit id="_msg833"> + <trans-unit id="_msg835"> <source xml:space="preserve">Credit</source> <context-group purpose="location"><context context-type="linenumber">194</context></context-group> <context-group purpose="location"><context context-type="linenumber">206</context></context-group> @@ -3838,98 +3846,98 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </trans-unit> <group restype="x-gettext-plurals"> <context-group purpose="location"><context context-type="linenumber">196</context></context-group> - <trans-unit id="_msg834[0]"> + <trans-unit id="_msg836[0]"> <source xml:space="preserve">matures in %n more block(s)</source> </trans-unit> - <trans-unit id="_msg834[1]"> + <trans-unit id="_msg836[1]"> <source xml:space="preserve">matures in %n more block(s)</source> </trans-unit> </group> - <trans-unit id="_msg835"> + <trans-unit id="_msg837"> <source xml:space="preserve">not accepted</source> <context-group purpose="location"><context context-type="linenumber">198</context></context-group> </trans-unit> - <trans-unit id="_msg836"> + <trans-unit id="_msg838"> <source xml:space="preserve">Debit</source> <context-group purpose="location"><context context-type="linenumber">258</context></context-group> <context-group purpose="location"><context context-type="linenumber">284</context></context-group> <context-group purpose="location"><context context-type="linenumber">347</context></context-group> </trans-unit> - <trans-unit id="_msg837"> + <trans-unit id="_msg839"> <source xml:space="preserve">Total debit</source> <context-group purpose="location"><context context-type="linenumber">268</context></context-group> </trans-unit> - <trans-unit id="_msg838"> + <trans-unit id="_msg840"> <source xml:space="preserve">Total credit</source> <context-group purpose="location"><context context-type="linenumber">269</context></context-group> </trans-unit> - <trans-unit id="_msg839"> + <trans-unit id="_msg841"> <source xml:space="preserve">Transaction fee</source> <context-group purpose="location"><context context-type="linenumber">274</context></context-group> </trans-unit> - <trans-unit id="_msg840"> + <trans-unit id="_msg842"> <source xml:space="preserve">Net amount</source> <context-group purpose="location"><context context-type="linenumber">296</context></context-group> </trans-unit> - <trans-unit id="_msg841"> + <trans-unit id="_msg843"> <source xml:space="preserve">Message</source> <context-group purpose="location"><context context-type="linenumber">302</context></context-group> <context-group purpose="location"><context context-type="linenumber">314</context></context-group> </trans-unit> - <trans-unit id="_msg842"> + <trans-unit id="_msg844"> <source xml:space="preserve">Comment</source> <context-group purpose="location"><context context-type="linenumber">304</context></context-group> </trans-unit> - <trans-unit id="_msg843"> + <trans-unit id="_msg845"> <source xml:space="preserve">Transaction ID</source> <context-group purpose="location"><context context-type="linenumber">306</context></context-group> </trans-unit> - <trans-unit id="_msg844"> + <trans-unit id="_msg846"> <source xml:space="preserve">Transaction total size</source> <context-group purpose="location"><context context-type="linenumber">307</context></context-group> </trans-unit> - <trans-unit id="_msg845"> + <trans-unit id="_msg847"> <source xml:space="preserve">Transaction virtual size</source> <context-group purpose="location"><context context-type="linenumber">308</context></context-group> </trans-unit> - <trans-unit id="_msg846"> + <trans-unit id="_msg848"> <source xml:space="preserve">Output index</source> <context-group purpose="location"><context context-type="linenumber">309</context></context-group> </trans-unit> - <trans-unit id="_msg847"> + <trans-unit id="_msg849"> <source xml:space="preserve"> (Certificate was not verified)</source> <context-group purpose="location"><context context-type="linenumber">325</context></context-group> </trans-unit> - <trans-unit id="_msg848"> + <trans-unit id="_msg850"> <source xml:space="preserve">Merchant</source> <context-group purpose="location"><context context-type="linenumber">328</context></context-group> </trans-unit> - <trans-unit id="_msg849"> + <trans-unit id="_msg851"> <source xml:space="preserve">Generated coins must mature %1 blocks before they can be spent. When you generated this block, it was broadcast to the network to be added to the block chain. If it fails to get into the chain, its state will change to "not accepted" and it won't be spendable. This may occasionally happen if another node generates a block within a few seconds of yours.</source> <context-group purpose="location"><context context-type="linenumber">336</context></context-group> </trans-unit> - <trans-unit id="_msg850"> + <trans-unit id="_msg852"> <source xml:space="preserve">Debug information</source> <context-group purpose="location"><context context-type="linenumber">344</context></context-group> </trans-unit> - <trans-unit id="_msg851"> + <trans-unit id="_msg853"> <source xml:space="preserve">Transaction</source> <context-group purpose="location"><context context-type="linenumber">352</context></context-group> </trans-unit> - <trans-unit id="_msg852"> + <trans-unit id="_msg854"> <source xml:space="preserve">Inputs</source> <context-group purpose="location"><context context-type="linenumber">355</context></context-group> </trans-unit> - <trans-unit id="_msg853"> + <trans-unit id="_msg855"> <source xml:space="preserve">Amount</source> <context-group purpose="location"><context context-type="linenumber">376</context></context-group> </trans-unit> - <trans-unit id="_msg854"> + <trans-unit id="_msg856"> <source xml:space="preserve">true</source> <context-group purpose="location"><context context-type="linenumber">377</context></context-group> <context-group purpose="location"><context context-type="linenumber">378</context></context-group> </trans-unit> - <trans-unit id="_msg855"> + <trans-unit id="_msg857"> <source xml:space="preserve">false</source> <context-group purpose="location"><context context-type="linenumber">377</context></context-group> <context-group purpose="location"><context context-type="linenumber">378</context></context-group> @@ -3938,7 +3946,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../forms/transactiondescdialog.ui" datatype="x-trolltech-designer-ui" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="TransactionDescDialog"> - <trans-unit id="_msg856"> + <trans-unit id="_msg858"> <source xml:space="preserve">This pane shows a detailed description of the transaction</source> <context-group purpose="location"><context context-type="linenumber">20</context></context-group> </trans-unit> @@ -3946,7 +3954,7 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../transactiondescdialog.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="TransactionDescDialog"> - <trans-unit id="_msg857"> + <trans-unit id="_msg859"> <source xml:space="preserve">Details for %1</source> <context-group purpose="location"><context context-type="linenumber">18</context></context-group> </trans-unit> @@ -3954,99 +3962,99 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../transactiontablemodel.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="TransactionTableModel"> - <trans-unit id="_msg858"> + <trans-unit id="_msg860"> <source xml:space="preserve">Date</source> <context-group purpose="location"><context context-type="linenumber">261</context></context-group> </trans-unit> - <trans-unit id="_msg859"> + <trans-unit id="_msg861"> <source xml:space="preserve">Type</source> <context-group purpose="location"><context context-type="linenumber">261</context></context-group> </trans-unit> - <trans-unit id="_msg860"> + <trans-unit id="_msg862"> <source xml:space="preserve">Label</source> <context-group purpose="location"><context context-type="linenumber">261</context></context-group> </trans-unit> - <trans-unit id="_msg861"> + <trans-unit id="_msg863"> <source xml:space="preserve">Unconfirmed</source> <context-group purpose="location"><context context-type="linenumber">321</context></context-group> </trans-unit> - <trans-unit id="_msg862"> + <trans-unit id="_msg864"> <source xml:space="preserve">Abandoned</source> <context-group purpose="location"><context context-type="linenumber">324</context></context-group> </trans-unit> - <trans-unit id="_msg863"> + <trans-unit id="_msg865"> <source xml:space="preserve">Confirming (%1 of %2 recommended confirmations)</source> <context-group purpose="location"><context context-type="linenumber">327</context></context-group> </trans-unit> - <trans-unit id="_msg864"> + <trans-unit id="_msg866"> <source xml:space="preserve">Confirmed (%1 confirmations)</source> <context-group purpose="location"><context context-type="linenumber">330</context></context-group> </trans-unit> - <trans-unit id="_msg865"> + <trans-unit id="_msg867"> <source xml:space="preserve">Conflicted</source> <context-group purpose="location"><context context-type="linenumber">333</context></context-group> </trans-unit> - <trans-unit id="_msg866"> + <trans-unit id="_msg868"> <source xml:space="preserve">Immature (%1 confirmations, will be available after %2)</source> <context-group purpose="location"><context context-type="linenumber">336</context></context-group> </trans-unit> - <trans-unit id="_msg867"> + <trans-unit id="_msg869"> <source xml:space="preserve">Generated but not accepted</source> <context-group purpose="location"><context context-type="linenumber">339</context></context-group> </trans-unit> - <trans-unit id="_msg868"> + <trans-unit id="_msg870"> <source xml:space="preserve">Received with</source> <context-group purpose="location"><context context-type="linenumber">378</context></context-group> </trans-unit> - <trans-unit id="_msg869"> + <trans-unit id="_msg871"> <source xml:space="preserve">Received from</source> <context-group purpose="location"><context context-type="linenumber">380</context></context-group> </trans-unit> - <trans-unit id="_msg870"> + <trans-unit id="_msg872"> <source xml:space="preserve">Sent to</source> <context-group purpose="location"><context context-type="linenumber">383</context></context-group> </trans-unit> - <trans-unit id="_msg871"> + <trans-unit id="_msg873"> <source xml:space="preserve">Payment to yourself</source> <context-group purpose="location"><context context-type="linenumber">385</context></context-group> </trans-unit> - <trans-unit id="_msg872"> + <trans-unit id="_msg874"> <source xml:space="preserve">Mined</source> <context-group purpose="location"><context context-type="linenumber">387</context></context-group> </trans-unit> - <trans-unit id="_msg873"> + <trans-unit id="_msg875"> <source xml:space="preserve">watch-only</source> <context-group purpose="location"><context context-type="linenumber">415</context></context-group> </trans-unit> - <trans-unit id="_msg874"> + <trans-unit id="_msg876"> <source xml:space="preserve">(n/a)</source> <context-group purpose="location"><context context-type="linenumber">431</context></context-group> </trans-unit> - <trans-unit id="_msg875"> + <trans-unit id="_msg877"> <source xml:space="preserve">(no label)</source> <context-group purpose="location"><context context-type="linenumber">638</context></context-group> </trans-unit> - <trans-unit id="_msg876"> + <trans-unit id="_msg878"> <source xml:space="preserve">Transaction status. Hover over this field to show number of confirmations.</source> <context-group purpose="location"><context context-type="linenumber">677</context></context-group> </trans-unit> - <trans-unit id="_msg877"> + <trans-unit id="_msg879"> <source xml:space="preserve">Date and time that the transaction was received.</source> <context-group purpose="location"><context context-type="linenumber">679</context></context-group> </trans-unit> - <trans-unit id="_msg878"> + <trans-unit id="_msg880"> <source xml:space="preserve">Type of transaction.</source> <context-group purpose="location"><context context-type="linenumber">681</context></context-group> </trans-unit> - <trans-unit id="_msg879"> + <trans-unit id="_msg881"> <source xml:space="preserve">Whether or not a watch-only address is involved in this transaction.</source> <context-group purpose="location"><context context-type="linenumber">683</context></context-group> </trans-unit> - <trans-unit id="_msg880"> + <trans-unit id="_msg882"> <source xml:space="preserve">User-defined intent/purpose of the transaction.</source> <context-group purpose="location"><context context-type="linenumber">685</context></context-group> </trans-unit> - <trans-unit id="_msg881"> + <trans-unit id="_msg883"> <source xml:space="preserve">Amount removed from or added to balance.</source> <context-group purpose="location"><context context-type="linenumber">687</context></context-group> </trans-unit> @@ -4054,166 +4062,166 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../transactionview.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="TransactionView"> - <trans-unit id="_msg882"> + <trans-unit id="_msg884"> <source xml:space="preserve">All</source> <context-group purpose="location"><context context-type="linenumber">73</context></context-group> <context-group purpose="location"><context context-type="linenumber">89</context></context-group> </trans-unit> - <trans-unit id="_msg883"> + <trans-unit id="_msg885"> <source xml:space="preserve">Today</source> <context-group purpose="location"><context context-type="linenumber">74</context></context-group> </trans-unit> - <trans-unit id="_msg884"> + <trans-unit id="_msg886"> <source xml:space="preserve">This week</source> <context-group purpose="location"><context context-type="linenumber">75</context></context-group> </trans-unit> - <trans-unit id="_msg885"> + <trans-unit id="_msg887"> <source xml:space="preserve">This month</source> <context-group purpose="location"><context context-type="linenumber">76</context></context-group> </trans-unit> - <trans-unit id="_msg886"> + <trans-unit id="_msg888"> <source xml:space="preserve">Last month</source> <context-group purpose="location"><context context-type="linenumber">77</context></context-group> </trans-unit> - <trans-unit id="_msg887"> + <trans-unit id="_msg889"> <source xml:space="preserve">This year</source> <context-group purpose="location"><context context-type="linenumber">78</context></context-group> </trans-unit> - <trans-unit id="_msg888"> + <trans-unit id="_msg890"> <source xml:space="preserve">Received with</source> <context-group purpose="location"><context context-type="linenumber">90</context></context-group> </trans-unit> - <trans-unit id="_msg889"> + <trans-unit id="_msg891"> <source xml:space="preserve">Sent to</source> <context-group purpose="location"><context context-type="linenumber">92</context></context-group> </trans-unit> - <trans-unit id="_msg890"> + <trans-unit id="_msg892"> <source xml:space="preserve">To yourself</source> <context-group purpose="location"><context context-type="linenumber">94</context></context-group> </trans-unit> - <trans-unit id="_msg891"> + <trans-unit id="_msg893"> <source xml:space="preserve">Mined</source> <context-group purpose="location"><context context-type="linenumber">95</context></context-group> </trans-unit> - <trans-unit id="_msg892"> + <trans-unit id="_msg894"> <source xml:space="preserve">Other</source> <context-group purpose="location"><context context-type="linenumber">96</context></context-group> </trans-unit> - <trans-unit id="_msg893"> + <trans-unit id="_msg895"> <source xml:space="preserve">Enter address, transaction id, or label to search</source> <context-group purpose="location"><context context-type="linenumber">101</context></context-group> </trans-unit> - <trans-unit id="_msg894"> + <trans-unit id="_msg896"> <source xml:space="preserve">Min amount</source> <context-group purpose="location"><context context-type="linenumber">105</context></context-group> </trans-unit> - <trans-unit id="_msg895"> + <trans-unit id="_msg897"> <source xml:space="preserve">Range…</source> <context-group purpose="location"><context context-type="linenumber">79</context></context-group> </trans-unit> - <trans-unit id="_msg896"> + <trans-unit id="_msg898"> <source xml:space="preserve">&Copy address</source> <context-group purpose="location"><context context-type="linenumber">169</context></context-group> </trans-unit> - <trans-unit id="_msg897"> + <trans-unit id="_msg899"> <source xml:space="preserve">Copy &label</source> <context-group purpose="location"><context context-type="linenumber">170</context></context-group> </trans-unit> - <trans-unit id="_msg898"> + <trans-unit id="_msg900"> <source xml:space="preserve">Copy &amount</source> <context-group purpose="location"><context context-type="linenumber">171</context></context-group> </trans-unit> - <trans-unit id="_msg899"> + <trans-unit id="_msg901"> <source xml:space="preserve">Copy transaction &ID</source> <context-group purpose="location"><context context-type="linenumber">172</context></context-group> </trans-unit> - <trans-unit id="_msg900"> + <trans-unit id="_msg902"> <source xml:space="preserve">Copy &raw transaction</source> <context-group purpose="location"><context context-type="linenumber">173</context></context-group> </trans-unit> - <trans-unit id="_msg901"> + <trans-unit id="_msg903"> <source xml:space="preserve">Copy full transaction &details</source> <context-group purpose="location"><context context-type="linenumber">174</context></context-group> </trans-unit> - <trans-unit id="_msg902"> + <trans-unit id="_msg904"> <source xml:space="preserve">&Show transaction details</source> <context-group purpose="location"><context context-type="linenumber">175</context></context-group> </trans-unit> - <trans-unit id="_msg903"> + <trans-unit id="_msg905"> <source xml:space="preserve">Increase transaction &fee</source> <context-group purpose="location"><context context-type="linenumber">177</context></context-group> </trans-unit> - <trans-unit id="_msg904"> + <trans-unit id="_msg906"> <source xml:space="preserve">A&bandon transaction</source> <context-group purpose="location"><context context-type="linenumber">180</context></context-group> </trans-unit> - <trans-unit id="_msg905"> + <trans-unit id="_msg907"> <source xml:space="preserve">&Edit address label</source> <context-group purpose="location"><context context-type="linenumber">181</context></context-group> </trans-unit> - <trans-unit id="_msg906"> + <trans-unit id="_msg908"> <source xml:space="preserve">Show in %1</source> <context-group purpose="location"><context context-type="linenumber">240</context></context-group> <note annotates="source" from="developer">Transactions table context menu action to show the selected transaction in a third-party block explorer. %1 is a stand-in argument for the URL of the explorer.</note> </trans-unit> - <trans-unit id="_msg907"> + <trans-unit id="_msg909"> <source xml:space="preserve">Export Transaction History</source> <context-group purpose="location"><context context-type="linenumber">359</context></context-group> </trans-unit> - <trans-unit id="_msg908"> + <trans-unit id="_msg910"> <source xml:space="preserve">Comma separated file</source> <context-group purpose="location"><context context-type="linenumber">362</context></context-group> <note annotates="source" from="developer">Expanded name of the CSV file format. See: https://en.wikipedia.org/wiki/Comma-separated_values.</note> </trans-unit> - <trans-unit id="_msg909"> + <trans-unit id="_msg911"> <source xml:space="preserve">Confirmed</source> <context-group purpose="location"><context context-type="linenumber">371</context></context-group> </trans-unit> - <trans-unit id="_msg910"> + <trans-unit id="_msg912"> <source xml:space="preserve">Watch-only</source> <context-group purpose="location"><context context-type="linenumber">373</context></context-group> </trans-unit> - <trans-unit id="_msg911"> + <trans-unit id="_msg913"> <source xml:space="preserve">Date</source> <context-group purpose="location"><context context-type="linenumber">374</context></context-group> </trans-unit> - <trans-unit id="_msg912"> + <trans-unit id="_msg914"> <source xml:space="preserve">Type</source> <context-group purpose="location"><context context-type="linenumber">375</context></context-group> </trans-unit> - <trans-unit id="_msg913"> + <trans-unit id="_msg915"> <source xml:space="preserve">Label</source> <context-group purpose="location"><context context-type="linenumber">376</context></context-group> </trans-unit> - <trans-unit id="_msg914"> + <trans-unit id="_msg916"> <source xml:space="preserve">Address</source> <context-group purpose="location"><context context-type="linenumber">377</context></context-group> </trans-unit> - <trans-unit id="_msg915"> + <trans-unit id="_msg917"> <source xml:space="preserve">ID</source> <context-group purpose="location"><context context-type="linenumber">379</context></context-group> </trans-unit> - <trans-unit id="_msg916"> + <trans-unit id="_msg918"> <source xml:space="preserve">Exporting Failed</source> <context-group purpose="location"><context context-type="linenumber">382</context></context-group> </trans-unit> - <trans-unit id="_msg917"> + <trans-unit id="_msg919"> <source xml:space="preserve">There was an error trying to save the transaction history to %1.</source> <context-group purpose="location"><context context-type="linenumber">382</context></context-group> </trans-unit> - <trans-unit id="_msg918"> + <trans-unit id="_msg920"> <source xml:space="preserve">Exporting Successful</source> <context-group purpose="location"><context context-type="linenumber">386</context></context-group> </trans-unit> - <trans-unit id="_msg919"> + <trans-unit id="_msg921"> <source xml:space="preserve">The transaction history was successfully saved to %1.</source> <context-group purpose="location"><context context-type="linenumber">386</context></context-group> </trans-unit> - <trans-unit id="_msg920"> + <trans-unit id="_msg922"> <source xml:space="preserve">Range:</source> <context-group purpose="location"><context context-type="linenumber">558</context></context-group> </trans-unit> - <trans-unit id="_msg921"> + <trans-unit id="_msg923"> <source xml:space="preserve">to</source> <context-group purpose="location"><context context-type="linenumber">566</context></context-group> </trans-unit> @@ -4221,39 +4229,39 @@ Note: Since the fee is calculated on a per-byte basis, a fee rate of "100 </body></file> <file original="../walletframe.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="WalletFrame"> - <trans-unit id="_msg922"> + <trans-unit id="_msg924"> <source xml:space="preserve">No wallet has been loaded. Go to File > Open Wallet to load a wallet. - OR -</source> <context-group purpose="location"><context context-type="linenumber">45</context></context-group> </trans-unit> - <trans-unit id="_msg923"> + <trans-unit id="_msg925"> <source xml:space="preserve">Create a new wallet</source> <context-group purpose="location"><context context-type="linenumber">50</context></context-group> </trans-unit> - <trans-unit id="_msg924"> + <trans-unit id="_msg926"> <source xml:space="preserve">Error</source> <context-group purpose="location"><context context-type="linenumber">201</context></context-group> <context-group purpose="location"><context context-type="linenumber">211</context></context-group> <context-group purpose="location"><context context-type="linenumber">229</context></context-group> </trans-unit> - <trans-unit id="_msg925"> + <trans-unit id="_msg927"> <source xml:space="preserve">Unable to decode PSBT from clipboard (invalid base64)</source> <context-group purpose="location"><context context-type="linenumber">201</context></context-group> </trans-unit> - <trans-unit id="_msg926"> + <trans-unit id="_msg928"> <source xml:space="preserve">Load Transaction Data</source> <context-group purpose="location"><context context-type="linenumber">207</context></context-group> </trans-unit> - <trans-unit id="_msg927"> + <trans-unit id="_msg929"> <source xml:space="preserve">Partially Signed Transaction (*.psbt)</source> <context-group purpose="location"><context context-type="linenumber">208</context></context-group> </trans-unit> - <trans-unit id="_msg928"> + <trans-unit id="_msg930"> <source xml:space="preserve">PSBT file must be smaller than 100 MiB</source> <context-group purpose="location"><context context-type="linenumber">211</context></context-group> </trans-unit> - <trans-unit id="_msg929"> + <trans-unit id="_msg931"> <source xml:space="preserve">Unable to decode PSBT</source> <context-group purpose="location"><context context-type="linenumber">229</context></context-group> </trans-unit> @@ -4261,108 +4269,108 @@ Go to File > Open Wallet to load a wallet. </body></file> <file original="../walletmodel.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="WalletModel"> - <trans-unit id="_msg930"> + <trans-unit id="_msg932"> <source xml:space="preserve">Send Coins</source> - <context-group purpose="location"><context context-type="linenumber">221</context></context-group> + <context-group purpose="location"><context context-type="linenumber">232</context></context-group> </trans-unit> - <trans-unit id="_msg931"> + <trans-unit id="_msg933"> <source xml:space="preserve">Fee bump error</source> - <context-group purpose="location"><context context-type="linenumber">484</context></context-group> - <context-group purpose="location"><context context-type="linenumber">536</context></context-group> - <context-group purpose="location"><context context-type="linenumber">551</context></context-group> - <context-group purpose="location"><context context-type="linenumber">556</context></context-group> + <context-group purpose="location"><context context-type="linenumber">495</context></context-group> + <context-group purpose="location"><context context-type="linenumber">547</context></context-group> + <context-group purpose="location"><context context-type="linenumber">562</context></context-group> + <context-group purpose="location"><context context-type="linenumber">567</context></context-group> </trans-unit> - <trans-unit id="_msg932"> + <trans-unit id="_msg934"> <source xml:space="preserve">Increasing transaction fee failed</source> - <context-group purpose="location"><context context-type="linenumber">484</context></context-group> + <context-group purpose="location"><context context-type="linenumber">495</context></context-group> </trans-unit> - <trans-unit id="_msg933"> + <trans-unit id="_msg935"> <source xml:space="preserve">Do you want to increase the fee?</source> - <context-group purpose="location"><context context-type="linenumber">491</context></context-group> + <context-group purpose="location"><context context-type="linenumber">502</context></context-group> <note annotates="source" from="developer">Asks a user if they would like to manually increase the fee of a transaction that has already been created.</note> </trans-unit> - <trans-unit id="_msg934"> + <trans-unit id="_msg936"> <source xml:space="preserve">Current fee:</source> - <context-group purpose="location"><context context-type="linenumber">495</context></context-group> + <context-group purpose="location"><context context-type="linenumber">506</context></context-group> </trans-unit> - <trans-unit id="_msg935"> + <trans-unit id="_msg937"> <source xml:space="preserve">Increase:</source> - <context-group purpose="location"><context context-type="linenumber">499</context></context-group> + <context-group purpose="location"><context context-type="linenumber">510</context></context-group> </trans-unit> - <trans-unit id="_msg936"> + <trans-unit id="_msg938"> <source xml:space="preserve">New fee:</source> - <context-group purpose="location"><context context-type="linenumber">503</context></context-group> + <context-group purpose="location"><context context-type="linenumber">514</context></context-group> </trans-unit> - <trans-unit id="_msg937"> + <trans-unit id="_msg939"> <source xml:space="preserve">Warning: This may pay the additional fee by reducing change outputs or adding inputs, when necessary. It may add a new change output if one does not already exist. These changes may potentially leak privacy.</source> - <context-group purpose="location"><context context-type="linenumber">511</context></context-group> + <context-group purpose="location"><context context-type="linenumber">522</context></context-group> </trans-unit> - <trans-unit id="_msg938"> + <trans-unit id="_msg940"> <source xml:space="preserve">Confirm fee bump</source> - <context-group purpose="location"><context context-type="linenumber">514</context></context-group> + <context-group purpose="location"><context context-type="linenumber">525</context></context-group> </trans-unit> - <trans-unit id="_msg939"> + <trans-unit id="_msg941"> <source xml:space="preserve">Can't draft transaction.</source> - <context-group purpose="location"><context context-type="linenumber">536</context></context-group> + <context-group purpose="location"><context context-type="linenumber">547</context></context-group> </trans-unit> - <trans-unit id="_msg940"> + <trans-unit id="_msg942"> <source xml:space="preserve">PSBT copied</source> - <context-group purpose="location"><context context-type="linenumber">543</context></context-group> + <context-group purpose="location"><context context-type="linenumber">554</context></context-group> </trans-unit> - <trans-unit id="_msg941"> + <trans-unit id="_msg943"> <source xml:space="preserve">Can't sign transaction.</source> - <context-group purpose="location"><context context-type="linenumber">551</context></context-group> + <context-group purpose="location"><context context-type="linenumber">562</context></context-group> </trans-unit> - <trans-unit id="_msg942"> + <trans-unit id="_msg944"> <source xml:space="preserve">Could not commit transaction</source> - <context-group purpose="location"><context context-type="linenumber">556</context></context-group> + <context-group purpose="location"><context context-type="linenumber">567</context></context-group> </trans-unit> - <trans-unit id="_msg943"> + <trans-unit id="_msg945"> <source xml:space="preserve">Can't display address</source> - <context-group purpose="location"><context context-type="linenumber">570</context></context-group> + <context-group purpose="location"><context context-type="linenumber">581</context></context-group> </trans-unit> - <trans-unit id="_msg944"> + <trans-unit id="_msg946"> <source xml:space="preserve">default wallet</source> - <context-group purpose="location"><context context-type="linenumber">588</context></context-group> + <context-group purpose="location"><context context-type="linenumber">599</context></context-group> </trans-unit> </group> </body></file> <file original="../walletview.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="WalletView"> - <trans-unit id="_msg945"> + <trans-unit id="_msg947"> <source xml:space="preserve">&Export</source> <context-group purpose="location"><context context-type="linenumber">51</context></context-group> </trans-unit> - <trans-unit id="_msg946"> + <trans-unit id="_msg948"> <source xml:space="preserve">Export the data in the current tab to a file</source> <context-group purpose="location"><context context-type="linenumber">52</context></context-group> </trans-unit> - <trans-unit id="_msg947"> + <trans-unit id="_msg949"> <source xml:space="preserve">Backup Wallet</source> <context-group purpose="location"><context context-type="linenumber">214</context></context-group> </trans-unit> - <trans-unit id="_msg948"> + <trans-unit id="_msg950"> <source xml:space="preserve">Wallet Data</source> <context-group purpose="location"><context context-type="linenumber">216</context></context-group> <note annotates="source" from="developer">Name of the wallet data file format.</note> </trans-unit> - <trans-unit id="_msg949"> + <trans-unit id="_msg951"> <source xml:space="preserve">Backup Failed</source> <context-group purpose="location"><context context-type="linenumber">222</context></context-group> </trans-unit> - <trans-unit id="_msg950"> + <trans-unit id="_msg952"> <source xml:space="preserve">There was an error trying to save the wallet data to %1.</source> <context-group purpose="location"><context context-type="linenumber">222</context></context-group> </trans-unit> - <trans-unit id="_msg951"> + <trans-unit id="_msg953"> <source xml:space="preserve">Backup Successful</source> <context-group purpose="location"><context context-type="linenumber">226</context></context-group> </trans-unit> - <trans-unit id="_msg952"> + <trans-unit id="_msg954"> <source xml:space="preserve">The wallet data was successfully saved to %1.</source> <context-group purpose="location"><context context-type="linenumber">226</context></context-group> </trans-unit> - <trans-unit id="_msg953"> + <trans-unit id="_msg955"> <source xml:space="preserve">Cancel</source> <context-group purpose="location"><context context-type="linenumber">263</context></context-group> </trans-unit> @@ -4370,690 +4378,694 @@ Go to File > Open Wallet to load a wallet. </body></file> <file original="../bitcoinstrings.cpp" datatype="cpp" source-language="en"><body> <group restype="x-trolltech-linguist-context" resname="bitcoin-core"> - <trans-unit id="_msg954"> + <trans-unit id="_msg956"> <source xml:space="preserve">The %s developers</source> <context-group purpose="location"><context context-type="linenumber">12</context></context-group> </trans-unit> - <trans-unit id="_msg955"> + <trans-unit id="_msg957"> <source xml:space="preserve">%s corrupt. Try using the wallet tool bitcoin-wallet to salvage or restoring a backup.</source> <context-group purpose="location"><context context-type="linenumber">13</context></context-group> </trans-unit> - <trans-unit id="_msg956"> + <trans-unit id="_msg958"> <source xml:space="preserve">-maxtxfee is set very high! Fees this large could be paid on a single transaction.</source> <context-group purpose="location"><context context-type="linenumber">20</context></context-group> </trans-unit> - <trans-unit id="_msg957"> + <trans-unit id="_msg959"> <source xml:space="preserve">Cannot downgrade wallet from version %i to version %i. Wallet version unchanged.</source> <context-group purpose="location"><context context-type="linenumber">38</context></context-group> </trans-unit> - <trans-unit id="_msg958"> + <trans-unit id="_msg960"> <source xml:space="preserve">Cannot obtain a lock on data directory %s. %s is probably already running.</source> <context-group purpose="location"><context context-type="linenumber">41</context></context-group> </trans-unit> - <trans-unit id="_msg959"> + <trans-unit id="_msg961"> <source xml:space="preserve">Cannot upgrade a non HD split wallet from version %i to version %i without upgrading to support pre-split keypool. Please use version %i or no version specified.</source> <context-group purpose="location"><context context-type="linenumber">46</context></context-group> </trans-unit> - <trans-unit id="_msg960"> + <trans-unit id="_msg962"> <source xml:space="preserve">Distributed under the MIT software license, see the accompanying file %s or %s</source> <context-group purpose="location"><context context-type="linenumber">50</context></context-group> </trans-unit> - <trans-unit id="_msg961"> + <trans-unit id="_msg963"> <source xml:space="preserve">Error reading %s! All keys read correctly, but transaction data or address book entries might be missing or incorrect.</source> <context-group purpose="location"><context context-type="linenumber">56</context></context-group> </trans-unit> - <trans-unit id="_msg962"> + <trans-unit id="_msg964"> <source xml:space="preserve">Error reading %s! Transaction data may be missing or incorrect. Rescanning wallet.</source> <context-group purpose="location"><context context-type="linenumber">59</context></context-group> </trans-unit> - <trans-unit id="_msg963"> + <trans-unit id="_msg965"> <source xml:space="preserve">Error: Dumpfile format record is incorrect. Got "%s", expected "format".</source> <context-group purpose="location"><context context-type="linenumber">62</context></context-group> </trans-unit> - <trans-unit id="_msg964"> + <trans-unit id="_msg966"> <source xml:space="preserve">Error: Dumpfile identifier record is incorrect. Got "%s", expected "%s".</source> <context-group purpose="location"><context context-type="linenumber">64</context></context-group> </trans-unit> - <trans-unit id="_msg965"> + <trans-unit id="_msg967"> <source xml:space="preserve">Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s</source> <context-group purpose="location"><context context-type="linenumber">66</context></context-group> </trans-unit> - <trans-unit id="_msg966"> + <trans-unit id="_msg968"> <source xml:space="preserve">Error: Legacy wallets only support the "legacy", "p2sh-segwit", and "bech32" address types</source> <context-group purpose="location"><context context-type="linenumber">69</context></context-group> </trans-unit> - <trans-unit id="_msg967"> + <trans-unit id="_msg969"> <source xml:space="preserve">Fee estimation failed. Fallbackfee is disabled. Wait a few blocks or enable -fallbackfee.</source> <context-group purpose="location"><context context-type="linenumber">75</context></context-group> </trans-unit> - <trans-unit id="_msg968"> + <trans-unit id="_msg970"> <source xml:space="preserve">File %s already exists. If you are sure this is what you want, move it out of the way first.</source> <context-group purpose="location"><context context-type="linenumber">78</context></context-group> </trans-unit> - <trans-unit id="_msg969"> + <trans-unit id="_msg971"> <source xml:space="preserve">Invalid amount for -maxtxfee=<amount>: '%s' (must be at least the minrelay fee of %s to prevent stuck transactions)</source> <context-group purpose="location"><context context-type="linenumber">81</context></context-group> </trans-unit> - <trans-unit id="_msg970"> + <trans-unit id="_msg972"> <source xml:space="preserve">Invalid or corrupt peers.dat (%s). If you believe this is a bug, please report it to %s. As a workaround, you can move the file (%s) out of the way (rename, move, or delete) to have a new one created on the next start.</source> <context-group purpose="location"><context context-type="linenumber">84</context></context-group> </trans-unit> - <trans-unit id="_msg971"> + <trans-unit id="_msg973"> <source xml:space="preserve">More than one onion bind address is provided. Using %s for the automatically created Tor onion service.</source> <context-group purpose="location"><context context-type="linenumber">88</context></context-group> </trans-unit> - <trans-unit id="_msg972"> + <trans-unit id="_msg974"> <source xml:space="preserve">No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided.</source> <context-group purpose="location"><context context-type="linenumber">91</context></context-group> </trans-unit> - <trans-unit id="_msg973"> + <trans-unit id="_msg975"> <source xml:space="preserve">No dump file provided. To use dump, -dumpfile=<filename> must be provided.</source> <context-group purpose="location"><context context-type="linenumber">94</context></context-group> </trans-unit> - <trans-unit id="_msg974"> + <trans-unit id="_msg976"> <source xml:space="preserve">No wallet file format provided. To use createfromdump, -format=<format> must be provided.</source> <context-group purpose="location"><context context-type="linenumber">96</context></context-group> </trans-unit> - <trans-unit id="_msg975"> + <trans-unit id="_msg977"> <source xml:space="preserve">Outbound connections restricted to Tor (-onlynet=onion) but the proxy for reaching the Tor network is not provided (no -proxy= and no -onion= given) or it is explicitly forbidden (-onion=0)</source> <context-group purpose="location"><context context-type="linenumber">99</context></context-group> </trans-unit> - <trans-unit id="_msg976"> + <trans-unit id="_msg978"> <source xml:space="preserve">Please check that your computer's date and time are correct! If your clock is wrong, %s will not work properly.</source> <context-group purpose="location"><context context-type="linenumber">103</context></context-group> </trans-unit> - <trans-unit id="_msg977"> + <trans-unit id="_msg979"> <source xml:space="preserve">Please contribute if you find %s useful. Visit %s for further information about the software.</source> <context-group purpose="location"><context context-type="linenumber">106</context></context-group> </trans-unit> - <trans-unit id="_msg978"> + <trans-unit id="_msg980"> <source xml:space="preserve">Prune configured below the minimum of %d MiB. Please use a higher number.</source> <context-group purpose="location"><context context-type="linenumber">109</context></context-group> </trans-unit> - <trans-unit id="_msg979"> + <trans-unit id="_msg981"> <source xml:space="preserve">Prune mode is incompatible with -reindex-chainstate. Use full -reindex instead.</source> <context-group purpose="location"><context context-type="linenumber">111</context></context-group> </trans-unit> - <trans-unit id="_msg980"> + <trans-unit id="_msg982"> <source xml:space="preserve">Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)</source> <context-group purpose="location"><context context-type="linenumber">114</context></context-group> </trans-unit> - <trans-unit id="_msg981"> + <trans-unit id="_msg983"> <source xml:space="preserve">SQLiteDatabase: Unknown sqlite wallet schema version %d. Only version %d is supported</source> <context-group purpose="location"><context context-type="linenumber">117</context></context-group> </trans-unit> - <trans-unit id="_msg982"> + <trans-unit id="_msg984"> <source xml:space="preserve">The block database contains a block which appears to be from the future. This may be due to your computer's date and time being set incorrectly. Only rebuild the block database if you are sure that your computer's date and time are correct</source> <context-group purpose="location"><context context-type="linenumber">123</context></context-group> </trans-unit> - <trans-unit id="_msg983"> + <trans-unit id="_msg985"> <source xml:space="preserve">The block index db contains a legacy 'txindex'. To clear the occupied disk space, run a full -reindex, otherwise ignore this error. This error message will not be displayed again.</source> <context-group purpose="location"><context context-type="linenumber">128</context></context-group> </trans-unit> - <trans-unit id="_msg984"> + <trans-unit id="_msg986"> <source xml:space="preserve">The transaction amount is too small to send after the fee has been deducted</source> <context-group purpose="location"><context context-type="linenumber">132</context></context-group> </trans-unit> - <trans-unit id="_msg985"> + <trans-unit id="_msg987"> <source xml:space="preserve">This error could occur if this wallet was not shutdown cleanly and was last loaded using a build with a newer version of Berkeley DB. If so, please use the software that last loaded this wallet</source> <context-group purpose="location"><context context-type="linenumber">134</context></context-group> </trans-unit> - <trans-unit id="_msg986"> + <trans-unit id="_msg988"> <source xml:space="preserve">This is a pre-release test build - use at your own risk - do not use for mining or merchant applications</source> <context-group purpose="location"><context context-type="linenumber">138</context></context-group> </trans-unit> - <trans-unit id="_msg987"> + <trans-unit id="_msg989"> <source xml:space="preserve">This is the maximum transaction fee you pay (in addition to the normal fee) to prioritize partial spend avoidance over regular coin selection.</source> <context-group purpose="location"><context context-type="linenumber">141</context></context-group> </trans-unit> - <trans-unit id="_msg988"> + <trans-unit id="_msg990"> <source xml:space="preserve">This is the transaction fee you may discard if change is smaller than dust at this level</source> <context-group purpose="location"><context context-type="linenumber">144</context></context-group> </trans-unit> - <trans-unit id="_msg989"> + <trans-unit id="_msg991"> <source xml:space="preserve">This is the transaction fee you may pay when fee estimates are not available.</source> <context-group purpose="location"><context context-type="linenumber">147</context></context-group> </trans-unit> - <trans-unit id="_msg990"> + <trans-unit id="_msg992"> <source xml:space="preserve">Total length of network version string (%i) exceeds maximum length (%i). Reduce the number or size of uacomments.</source> <context-group purpose="location"><context context-type="linenumber">149</context></context-group> </trans-unit> - <trans-unit id="_msg991"> + <trans-unit id="_msg993"> <source xml:space="preserve">Unable to replay blocks. You will need to rebuild the database using -reindex-chainstate.</source> <context-group purpose="location"><context context-type="linenumber">152</context></context-group> </trans-unit> - <trans-unit id="_msg992"> + <trans-unit id="_msg994"> <source xml:space="preserve">Unknown wallet file format "%s" provided. Please provide one of "bdb" or "sqlite".</source> <context-group purpose="location"><context context-type="linenumber">155</context></context-group> </trans-unit> - <trans-unit id="_msg993"> + <trans-unit id="_msg995"> <source xml:space="preserve">Unsupported chainstate database format found. Please restart with -reindex-chainstate. This will rebuild the chainstate database.</source> <context-group purpose="location"><context context-type="linenumber">158</context></context-group> </trans-unit> - <trans-unit id="_msg994"> + <trans-unit id="_msg996"> <source xml:space="preserve">Wallet created successfully. The legacy wallet type is being deprecated and support for creating and opening legacy wallets will be removed in the future.</source> <context-group purpose="location"><context context-type="linenumber">161</context></context-group> </trans-unit> - <trans-unit id="_msg995"> + <trans-unit id="_msg997"> <source xml:space="preserve">Warning: Dumpfile wallet format "%s" does not match command line specified format "%s".</source> <context-group purpose="location"><context context-type="linenumber">165</context></context-group> </trans-unit> - <trans-unit id="_msg996"> + <trans-unit id="_msg998"> <source xml:space="preserve">Warning: Private keys detected in wallet {%s} with disabled private keys</source> <context-group purpose="location"><context context-type="linenumber">168</context></context-group> </trans-unit> - <trans-unit id="_msg997"> + <trans-unit id="_msg999"> <source xml:space="preserve">Warning: We do not appear to fully agree with our peers! You may need to upgrade, or other nodes may need to upgrade.</source> <context-group purpose="location"><context context-type="linenumber">170</context></context-group> </trans-unit> - <trans-unit id="_msg998"> + <trans-unit id="_msg1000"> <source xml:space="preserve">Witness data for blocks after height %d requires validation. Please restart with -reindex.</source> <context-group purpose="location"><context context-type="linenumber">173</context></context-group> </trans-unit> - <trans-unit id="_msg999"> + <trans-unit id="_msg1001"> <source xml:space="preserve">You need to rebuild the database using -reindex to go back to unpruned mode. This will redownload the entire blockchain</source> <context-group purpose="location"><context context-type="linenumber">176</context></context-group> </trans-unit> - <trans-unit id="_msg1000"> + <trans-unit id="_msg1002"> <source xml:space="preserve">%s is set very high!</source> <context-group purpose="location"><context context-type="linenumber">179</context></context-group> </trans-unit> - <trans-unit id="_msg1001"> + <trans-unit id="_msg1003"> <source xml:space="preserve">-maxmempool must be at least %d MB</source> <context-group purpose="location"><context context-type="linenumber">180</context></context-group> </trans-unit> - <trans-unit id="_msg1002"> + <trans-unit id="_msg1004"> <source xml:space="preserve">A fatal internal error occurred, see debug.log for details</source> <context-group purpose="location"><context context-type="linenumber">181</context></context-group> </trans-unit> - <trans-unit id="_msg1003"> + <trans-unit id="_msg1005"> <source xml:space="preserve">Cannot resolve -%s address: '%s'</source> <context-group purpose="location"><context context-type="linenumber">182</context></context-group> </trans-unit> - <trans-unit id="_msg1004"> + <trans-unit id="_msg1006"> <source xml:space="preserve">Cannot set -forcednsseed to true when setting -dnsseed to false.</source> <context-group purpose="location"><context context-type="linenumber">183</context></context-group> </trans-unit> - <trans-unit id="_msg1005"> + <trans-unit id="_msg1007"> <source xml:space="preserve">Cannot set -peerblockfilters without -blockfilterindex.</source> <context-group purpose="location"><context context-type="linenumber">184</context></context-group> </trans-unit> - <trans-unit id="_msg1006"> + <trans-unit id="_msg1008"> <source xml:space="preserve">Cannot write to data directory '%s'; check permissions.</source> <context-group purpose="location"><context context-type="linenumber">185</context></context-group> </trans-unit> - <trans-unit id="_msg1007"> + <trans-unit id="_msg1009"> <source xml:space="preserve">The -txindex upgrade started by a previous version cannot be completed. Restart with the previous version or run a full -reindex.</source> <context-group purpose="location"><context context-type="linenumber">120</context></context-group> </trans-unit> - <trans-unit id="_msg1008"> + <trans-unit id="_msg1010"> <source xml:space="preserve">%s request to listen on port %u. This port is considered "bad" and thus it is unlikely that any Bitcoin Core peers connect to it. See doc/p2p-bad-ports.md for details and a full list.</source> <context-group purpose="location"><context context-type="linenumber">16</context></context-group> </trans-unit> - <trans-unit id="_msg1009"> + <trans-unit id="_msg1011"> <source xml:space="preserve">-reindex-chainstate option is not compatible with -blockfilterindex. Please temporarily disable blockfilterindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.</source> <context-group purpose="location"><context context-type="linenumber">23</context></context-group> </trans-unit> - <trans-unit id="_msg1010"> + <trans-unit id="_msg1012"> <source xml:space="preserve">-reindex-chainstate option is not compatible with -coinstatsindex. Please temporarily disable coinstatsindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.</source> <context-group purpose="location"><context context-type="linenumber">27</context></context-group> </trans-unit> - <trans-unit id="_msg1011"> + <trans-unit id="_msg1013"> <source xml:space="preserve">-reindex-chainstate option is not compatible with -txindex. Please temporarily disable txindex while using -reindex-chainstate, or replace -reindex-chainstate with -reindex to fully rebuild all indexes.</source> <context-group purpose="location"><context context-type="linenumber">31</context></context-group> </trans-unit> - <trans-unit id="_msg1012"> + <trans-unit id="_msg1014"> <source xml:space="preserve">Assumed-valid: last wallet synchronisation goes beyond available block data. You need to wait for the background validation chain to download more blocks.</source> <context-group purpose="location"><context context-type="linenumber">35</context></context-group> </trans-unit> - <trans-unit id="_msg1013"> + <trans-unit id="_msg1015"> <source xml:space="preserve">Cannot provide specific connections and have addrman find outgoing connections at the same time.</source> <context-group purpose="location"><context context-type="linenumber">43</context></context-group> </trans-unit> - <trans-unit id="_msg1014"> + <trans-unit id="_msg1016"> <source xml:space="preserve">Error loading %s: External signer wallet being loaded without external signer support compiled</source> <context-group purpose="location"><context context-type="linenumber">53</context></context-group> </trans-unit> - <trans-unit id="_msg1015"> + <trans-unit id="_msg1017"> <source xml:space="preserve">Failed to rename invalid peers.dat file. Please move or delete it and try again.</source> <context-group purpose="location"><context context-type="linenumber">72</context></context-group> </trans-unit> - <trans-unit id="_msg1016"> + <trans-unit id="_msg1018"> <source xml:space="preserve">Config setting for %s only applied on %s network when in [%s] section.</source> <context-group purpose="location"><context context-type="linenumber">186</context></context-group> </trans-unit> - <trans-unit id="_msg1017"> + <trans-unit id="_msg1019"> <source xml:space="preserve">Copyright (C) %i-%i</source> <context-group purpose="location"><context context-type="linenumber">187</context></context-group> </trans-unit> - <trans-unit id="_msg1018"> + <trans-unit id="_msg1020"> <source xml:space="preserve">Corrupted block database detected</source> <context-group purpose="location"><context context-type="linenumber">188</context></context-group> </trans-unit> - <trans-unit id="_msg1019"> + <trans-unit id="_msg1021"> <source xml:space="preserve">Could not find asmap file %s</source> <context-group purpose="location"><context context-type="linenumber">189</context></context-group> </trans-unit> - <trans-unit id="_msg1020"> + <trans-unit id="_msg1022"> <source xml:space="preserve">Could not parse asmap file %s</source> <context-group purpose="location"><context context-type="linenumber">190</context></context-group> </trans-unit> - <trans-unit id="_msg1021"> + <trans-unit id="_msg1023"> <source xml:space="preserve">Disk space is too low!</source> <context-group purpose="location"><context context-type="linenumber">191</context></context-group> </trans-unit> - <trans-unit id="_msg1022"> + <trans-unit id="_msg1024"> <source xml:space="preserve">Do you want to rebuild the block database now?</source> <context-group purpose="location"><context context-type="linenumber">192</context></context-group> </trans-unit> - <trans-unit id="_msg1023"> + <trans-unit id="_msg1025"> <source xml:space="preserve">Done loading</source> <context-group purpose="location"><context context-type="linenumber">193</context></context-group> </trans-unit> - <trans-unit id="_msg1024"> + <trans-unit id="_msg1026"> <source xml:space="preserve">Dump file %s does not exist.</source> <context-group purpose="location"><context context-type="linenumber">194</context></context-group> </trans-unit> - <trans-unit id="_msg1025"> + <trans-unit id="_msg1027"> <source xml:space="preserve">Error creating %s</source> <context-group purpose="location"><context context-type="linenumber">195</context></context-group> </trans-unit> - <trans-unit id="_msg1026"> + <trans-unit id="_msg1028"> <source xml:space="preserve">Error initializing block database</source> <context-group purpose="location"><context context-type="linenumber">196</context></context-group> </trans-unit> - <trans-unit id="_msg1027"> + <trans-unit id="_msg1029"> <source xml:space="preserve">Error initializing wallet database environment %s!</source> <context-group purpose="location"><context context-type="linenumber">197</context></context-group> </trans-unit> - <trans-unit id="_msg1028"> + <trans-unit id="_msg1030"> <source xml:space="preserve">Error loading %s</source> <context-group purpose="location"><context context-type="linenumber">198</context></context-group> </trans-unit> - <trans-unit id="_msg1029"> + <trans-unit id="_msg1031"> <source xml:space="preserve">Error loading %s: Private keys can only be disabled during creation</source> <context-group purpose="location"><context context-type="linenumber">199</context></context-group> </trans-unit> - <trans-unit id="_msg1030"> + <trans-unit id="_msg1032"> <source xml:space="preserve">Error loading %s: Wallet corrupted</source> <context-group purpose="location"><context context-type="linenumber">200</context></context-group> </trans-unit> - <trans-unit id="_msg1031"> + <trans-unit id="_msg1033"> <source xml:space="preserve">Error loading %s: Wallet requires newer version of %s</source> <context-group purpose="location"><context context-type="linenumber">201</context></context-group> </trans-unit> - <trans-unit id="_msg1032"> + <trans-unit id="_msg1034"> <source xml:space="preserve">Error loading block database</source> <context-group purpose="location"><context context-type="linenumber">202</context></context-group> </trans-unit> - <trans-unit id="_msg1033"> + <trans-unit id="_msg1035"> <source xml:space="preserve">Error opening block database</source> <context-group purpose="location"><context context-type="linenumber">203</context></context-group> </trans-unit> - <trans-unit id="_msg1034"> + <trans-unit id="_msg1036"> <source xml:space="preserve">Error reading from database, shutting down.</source> <context-group purpose="location"><context context-type="linenumber">204</context></context-group> </trans-unit> - <trans-unit id="_msg1035"> + <trans-unit id="_msg1037"> <source xml:space="preserve">Error reading next record from wallet database</source> <context-group purpose="location"><context context-type="linenumber">205</context></context-group> </trans-unit> - <trans-unit id="_msg1036"> + <trans-unit id="_msg1038"> <source xml:space="preserve">Error: Couldn't create cursor into database</source> <context-group purpose="location"><context context-type="linenumber">206</context></context-group> </trans-unit> - <trans-unit id="_msg1037"> + <trans-unit id="_msg1039"> <source xml:space="preserve">Error: Disk space is low for %s</source> <context-group purpose="location"><context context-type="linenumber">207</context></context-group> </trans-unit> - <trans-unit id="_msg1038"> + <trans-unit id="_msg1040"> <source xml:space="preserve">Error: Dumpfile checksum does not match. Computed %s, expected %s</source> <context-group purpose="location"><context context-type="linenumber">208</context></context-group> </trans-unit> - <trans-unit id="_msg1039"> + <trans-unit id="_msg1041"> <source xml:space="preserve">Error: Got key that was not hex: %s</source> <context-group purpose="location"><context context-type="linenumber">209</context></context-group> </trans-unit> - <trans-unit id="_msg1040"> + <trans-unit id="_msg1042"> <source xml:space="preserve">Error: Got value that was not hex: %s</source> <context-group purpose="location"><context context-type="linenumber">210</context></context-group> </trans-unit> - <trans-unit id="_msg1041"> + <trans-unit id="_msg1043"> <source xml:space="preserve">Error: Keypool ran out, please call keypoolrefill first</source> <context-group purpose="location"><context context-type="linenumber">211</context></context-group> </trans-unit> - <trans-unit id="_msg1042"> + <trans-unit id="_msg1044"> <source xml:space="preserve">Error: Missing checksum</source> <context-group purpose="location"><context context-type="linenumber">212</context></context-group> </trans-unit> - <trans-unit id="_msg1043"> + <trans-unit id="_msg1045"> <source xml:space="preserve">Error: No %s addresses available.</source> <context-group purpose="location"><context context-type="linenumber">213</context></context-group> </trans-unit> - <trans-unit id="_msg1044"> + <trans-unit id="_msg1046"> <source xml:space="preserve">Error: Unable to parse version %u as a uint32_t</source> <context-group purpose="location"><context context-type="linenumber">214</context></context-group> </trans-unit> - <trans-unit id="_msg1045"> + <trans-unit id="_msg1047"> <source xml:space="preserve">Error: Unable to write record to new wallet</source> <context-group purpose="location"><context context-type="linenumber">215</context></context-group> </trans-unit> - <trans-unit id="_msg1046"> + <trans-unit id="_msg1048"> <source xml:space="preserve">Failed to listen on any port. Use -listen=0 if you want this.</source> <context-group purpose="location"><context context-type="linenumber">216</context></context-group> </trans-unit> - <trans-unit id="_msg1047"> + <trans-unit id="_msg1049"> <source xml:space="preserve">Failed to rescan the wallet during initialization</source> <context-group purpose="location"><context context-type="linenumber">217</context></context-group> </trans-unit> - <trans-unit id="_msg1048"> + <trans-unit id="_msg1050"> <source xml:space="preserve">Failed to verify database</source> <context-group purpose="location"><context context-type="linenumber">218</context></context-group> </trans-unit> - <trans-unit id="_msg1049"> + <trans-unit id="_msg1051"> <source xml:space="preserve">Fee rate (%s) is lower than the minimum fee rate setting (%s)</source> <context-group purpose="location"><context context-type="linenumber">219</context></context-group> </trans-unit> - <trans-unit id="_msg1050"> + <trans-unit id="_msg1052"> <source xml:space="preserve">Ignoring duplicate -wallet %s.</source> <context-group purpose="location"><context context-type="linenumber">220</context></context-group> </trans-unit> - <trans-unit id="_msg1051"> + <trans-unit id="_msg1053"> <source xml:space="preserve">Importing…</source> <context-group purpose="location"><context context-type="linenumber">221</context></context-group> </trans-unit> - <trans-unit id="_msg1052"> + <trans-unit id="_msg1054"> <source xml:space="preserve">Incorrect or no genesis block found. Wrong datadir for network?</source> <context-group purpose="location"><context context-type="linenumber">222</context></context-group> </trans-unit> - <trans-unit id="_msg1053"> + <trans-unit id="_msg1055"> <source xml:space="preserve">Initialization sanity check failed. %s is shutting down.</source> <context-group purpose="location"><context context-type="linenumber">223</context></context-group> </trans-unit> - <trans-unit id="_msg1054"> + <trans-unit id="_msg1056"> <source xml:space="preserve">Input not found or already spent</source> <context-group purpose="location"><context context-type="linenumber">224</context></context-group> </trans-unit> - <trans-unit id="_msg1055"> + <trans-unit id="_msg1057"> <source xml:space="preserve">Insufficient funds</source> <context-group purpose="location"><context context-type="linenumber">225</context></context-group> </trans-unit> - <trans-unit id="_msg1056"> + <trans-unit id="_msg1058"> <source xml:space="preserve">Invalid -i2psam address or hostname: '%s'</source> <context-group purpose="location"><context context-type="linenumber">226</context></context-group> </trans-unit> - <trans-unit id="_msg1057"> + <trans-unit id="_msg1059"> <source xml:space="preserve">Invalid -onion address or hostname: '%s'</source> <context-group purpose="location"><context context-type="linenumber">227</context></context-group> </trans-unit> - <trans-unit id="_msg1058"> + <trans-unit id="_msg1060"> <source xml:space="preserve">Invalid -proxy address or hostname: '%s'</source> <context-group purpose="location"><context context-type="linenumber">228</context></context-group> </trans-unit> - <trans-unit id="_msg1059"> + <trans-unit id="_msg1061"> <source xml:space="preserve">Invalid P2P permission: '%s'</source> <context-group purpose="location"><context context-type="linenumber">229</context></context-group> </trans-unit> - <trans-unit id="_msg1060"> + <trans-unit id="_msg1062"> <source xml:space="preserve">Invalid amount for -%s=<amount>: '%s'</source> <context-group purpose="location"><context context-type="linenumber">230</context></context-group> </trans-unit> - <trans-unit id="_msg1061"> + <trans-unit id="_msg1063"> <source xml:space="preserve">Invalid amount for -discardfee=<amount>: '%s'</source> <context-group purpose="location"><context context-type="linenumber">231</context></context-group> </trans-unit> - <trans-unit id="_msg1062"> + <trans-unit id="_msg1064"> <source xml:space="preserve">Invalid amount for -fallbackfee=<amount>: '%s'</source> <context-group purpose="location"><context context-type="linenumber">232</context></context-group> </trans-unit> - <trans-unit id="_msg1063"> + <trans-unit id="_msg1065"> <source xml:space="preserve">Invalid amount for -paytxfee=<amount>: '%s' (must be at least %s)</source> <context-group purpose="location"><context context-type="linenumber">233</context></context-group> </trans-unit> - <trans-unit id="_msg1064"> + <trans-unit id="_msg1066"> <source xml:space="preserve">Invalid netmask specified in -whitelist: '%s'</source> <context-group purpose="location"><context context-type="linenumber">234</context></context-group> </trans-unit> - <trans-unit id="_msg1065"> + <trans-unit id="_msg1067"> <source xml:space="preserve">Listening for incoming connections failed (listen returned error %s)</source> <context-group purpose="location"><context context-type="linenumber">235</context></context-group> </trans-unit> - <trans-unit id="_msg1066"> + <trans-unit id="_msg1068"> <source xml:space="preserve">Loading P2P addresses…</source> <context-group purpose="location"><context context-type="linenumber">236</context></context-group> </trans-unit> - <trans-unit id="_msg1067"> + <trans-unit id="_msg1069"> <source xml:space="preserve">Loading banlist…</source> <context-group purpose="location"><context context-type="linenumber">237</context></context-group> </trans-unit> - <trans-unit id="_msg1068"> + <trans-unit id="_msg1070"> <source xml:space="preserve">Loading block index…</source> <context-group purpose="location"><context context-type="linenumber">238</context></context-group> </trans-unit> - <trans-unit id="_msg1069"> + <trans-unit id="_msg1071"> <source xml:space="preserve">Loading wallet…</source> <context-group purpose="location"><context context-type="linenumber">239</context></context-group> </trans-unit> - <trans-unit id="_msg1070"> + <trans-unit id="_msg1072"> <source xml:space="preserve">Missing amount</source> <context-group purpose="location"><context context-type="linenumber">240</context></context-group> </trans-unit> - <trans-unit id="_msg1071"> + <trans-unit id="_msg1073"> <source xml:space="preserve">Missing solving data for estimating transaction size</source> <context-group purpose="location"><context context-type="linenumber">241</context></context-group> </trans-unit> - <trans-unit id="_msg1072"> + <trans-unit id="_msg1074"> <source xml:space="preserve">Need to specify a port with -whitebind: '%s'</source> <context-group purpose="location"><context context-type="linenumber">242</context></context-group> </trans-unit> - <trans-unit id="_msg1073"> + <trans-unit id="_msg1075"> <source xml:space="preserve">No addresses available</source> <context-group purpose="location"><context context-type="linenumber">243</context></context-group> </trans-unit> - <trans-unit id="_msg1074"> + <trans-unit id="_msg1076"> <source xml:space="preserve">Not enough file descriptors available.</source> <context-group purpose="location"><context context-type="linenumber">244</context></context-group> </trans-unit> - <trans-unit id="_msg1075"> + <trans-unit id="_msg1077"> <source xml:space="preserve">Prune cannot be configured with a negative value.</source> <context-group purpose="location"><context context-type="linenumber">245</context></context-group> </trans-unit> - <trans-unit id="_msg1076"> + <trans-unit id="_msg1078"> <source xml:space="preserve">Prune mode is incompatible with -txindex.</source> <context-group purpose="location"><context context-type="linenumber">246</context></context-group> </trans-unit> - <trans-unit id="_msg1077"> + <trans-unit id="_msg1079"> <source xml:space="preserve">Pruning blockstore…</source> <context-group purpose="location"><context context-type="linenumber">247</context></context-group> </trans-unit> - <trans-unit id="_msg1078"> + <trans-unit id="_msg1080"> <source xml:space="preserve">Reducing -maxconnections from %d to %d, because of system limitations.</source> <context-group purpose="location"><context context-type="linenumber">248</context></context-group> </trans-unit> - <trans-unit id="_msg1079"> + <trans-unit id="_msg1081"> <source xml:space="preserve">Replaying blocks…</source> <context-group purpose="location"><context context-type="linenumber">249</context></context-group> </trans-unit> - <trans-unit id="_msg1080"> + <trans-unit id="_msg1082"> <source xml:space="preserve">Rescanning…</source> <context-group purpose="location"><context context-type="linenumber">250</context></context-group> </trans-unit> - <trans-unit id="_msg1081"> + <trans-unit id="_msg1083"> <source xml:space="preserve">SQLiteDatabase: Failed to execute statement to verify database: %s</source> <context-group purpose="location"><context context-type="linenumber">251</context></context-group> </trans-unit> - <trans-unit id="_msg1082"> + <trans-unit id="_msg1084"> <source xml:space="preserve">SQLiteDatabase: Failed to prepare statement to verify database: %s</source> <context-group purpose="location"><context context-type="linenumber">252</context></context-group> </trans-unit> - <trans-unit id="_msg1083"> + <trans-unit id="_msg1085"> <source xml:space="preserve">SQLiteDatabase: Failed to read database verification error: %s</source> <context-group purpose="location"><context context-type="linenumber">253</context></context-group> </trans-unit> - <trans-unit id="_msg1084"> + <trans-unit id="_msg1086"> <source xml:space="preserve">SQLiteDatabase: Unexpected application id. Expected %u, got %u</source> <context-group purpose="location"><context context-type="linenumber">254</context></context-group> </trans-unit> - <trans-unit id="_msg1085"> + <trans-unit id="_msg1087"> <source xml:space="preserve">Section [%s] is not recognized.</source> <context-group purpose="location"><context context-type="linenumber">255</context></context-group> </trans-unit> - <trans-unit id="_msg1086"> + <trans-unit id="_msg1088"> <source xml:space="preserve">Signing transaction failed</source> <context-group purpose="location"><context context-type="linenumber">256</context></context-group> </trans-unit> - <trans-unit id="_msg1087"> + <trans-unit id="_msg1089"> <source xml:space="preserve">Specified -walletdir "%s" does not exist</source> <context-group purpose="location"><context context-type="linenumber">257</context></context-group> </trans-unit> - <trans-unit id="_msg1088"> + <trans-unit id="_msg1090"> <source xml:space="preserve">Specified -walletdir "%s" is a relative path</source> <context-group purpose="location"><context context-type="linenumber">258</context></context-group> </trans-unit> - <trans-unit id="_msg1089"> + <trans-unit id="_msg1091"> <source xml:space="preserve">Specified -walletdir "%s" is not a directory</source> <context-group purpose="location"><context context-type="linenumber">259</context></context-group> </trans-unit> - <trans-unit id="_msg1090"> + <trans-unit id="_msg1092"> <source xml:space="preserve">Specified blocks directory "%s" does not exist.</source> <context-group purpose="location"><context context-type="linenumber">260</context></context-group> </trans-unit> - <trans-unit id="_msg1091"> + <trans-unit id="_msg1093"> <source xml:space="preserve">Starting network threads…</source> <context-group purpose="location"><context context-type="linenumber">261</context></context-group> </trans-unit> - <trans-unit id="_msg1092"> + <trans-unit id="_msg1094"> <source xml:space="preserve">The source code is available from %s.</source> <context-group purpose="location"><context context-type="linenumber">262</context></context-group> </trans-unit> - <trans-unit id="_msg1093"> + <trans-unit id="_msg1095"> <source xml:space="preserve">The specified config file %s does not exist</source> <context-group purpose="location"><context context-type="linenumber">263</context></context-group> </trans-unit> - <trans-unit id="_msg1094"> + <trans-unit id="_msg1096"> <source xml:space="preserve">The transaction amount is too small to pay the fee</source> <context-group purpose="location"><context context-type="linenumber">264</context></context-group> </trans-unit> - <trans-unit id="_msg1095"> + <trans-unit id="_msg1097"> <source xml:space="preserve">The wallet will avoid paying less than the minimum relay fee.</source> <context-group purpose="location"><context context-type="linenumber">265</context></context-group> </trans-unit> - <trans-unit id="_msg1096"> + <trans-unit id="_msg1098"> <source xml:space="preserve">This is experimental software.</source> <context-group purpose="location"><context context-type="linenumber">266</context></context-group> </trans-unit> - <trans-unit id="_msg1097"> + <trans-unit id="_msg1099"> <source xml:space="preserve">This is the minimum transaction fee you pay on every transaction.</source> <context-group purpose="location"><context context-type="linenumber">267</context></context-group> </trans-unit> - <trans-unit id="_msg1098"> + <trans-unit id="_msg1100"> <source xml:space="preserve">This is the transaction fee you will pay if you send a transaction.</source> <context-group purpose="location"><context context-type="linenumber">268</context></context-group> </trans-unit> - <trans-unit id="_msg1099"> + <trans-unit id="_msg1101"> <source xml:space="preserve">Transaction amount too small</source> <context-group purpose="location"><context context-type="linenumber">269</context></context-group> </trans-unit> - <trans-unit id="_msg1100"> + <trans-unit id="_msg1102"> <source xml:space="preserve">Transaction amounts must not be negative</source> <context-group purpose="location"><context context-type="linenumber">270</context></context-group> </trans-unit> - <trans-unit id="_msg1101"> + <trans-unit id="_msg1103"> <source xml:space="preserve">Transaction change output index out of range</source> <context-group purpose="location"><context context-type="linenumber">271</context></context-group> </trans-unit> - <trans-unit id="_msg1102"> + <trans-unit id="_msg1104"> <source xml:space="preserve">Transaction has too long of a mempool chain</source> <context-group purpose="location"><context context-type="linenumber">272</context></context-group> </trans-unit> - <trans-unit id="_msg1103"> + <trans-unit id="_msg1105"> <source xml:space="preserve">Transaction must have at least one recipient</source> <context-group purpose="location"><context context-type="linenumber">273</context></context-group> </trans-unit> - <trans-unit id="_msg1104"> + <trans-unit id="_msg1106"> <source xml:space="preserve">Transaction needs a change address, but we can't generate it.</source> <context-group purpose="location"><context context-type="linenumber">274</context></context-group> </trans-unit> - <trans-unit id="_msg1105"> + <trans-unit id="_msg1107"> <source xml:space="preserve">Transaction too large</source> <context-group purpose="location"><context context-type="linenumber">275</context></context-group> </trans-unit> - <trans-unit id="_msg1106"> + <trans-unit id="_msg1108"> <source xml:space="preserve">Unable to allocate memory for -maxsigcachesize: '%s' MiB</source> <context-group purpose="location"><context context-type="linenumber">276</context></context-group> </trans-unit> - <trans-unit id="_msg1107"> + <trans-unit id="_msg1109"> <source xml:space="preserve">Unable to bind to %s on this computer (bind returned error %s)</source> <context-group purpose="location"><context context-type="linenumber">277</context></context-group> </trans-unit> - <trans-unit id="_msg1108"> + <trans-unit id="_msg1110"> <source xml:space="preserve">Unable to bind to %s on this computer. %s is probably already running.</source> <context-group purpose="location"><context context-type="linenumber">278</context></context-group> </trans-unit> - <trans-unit id="_msg1109"> + <trans-unit id="_msg1111"> <source xml:space="preserve">Unable to create the PID file '%s': %s</source> <context-group purpose="location"><context context-type="linenumber">279</context></context-group> </trans-unit> - <trans-unit id="_msg1110"> - <source xml:space="preserve">Unable to generate initial keys</source> + <trans-unit id="_msg1112"> + <source xml:space="preserve">Unable to find UTXO for external input</source> <context-group purpose="location"><context context-type="linenumber">280</context></context-group> </trans-unit> - <trans-unit id="_msg1111"> - <source xml:space="preserve">Unable to generate keys</source> + <trans-unit id="_msg1113"> + <source xml:space="preserve">Unable to generate initial keys</source> <context-group purpose="location"><context context-type="linenumber">281</context></context-group> </trans-unit> - <trans-unit id="_msg1112"> - <source xml:space="preserve">Unable to open %s for writing</source> + <trans-unit id="_msg1114"> + <source xml:space="preserve">Unable to generate keys</source> <context-group purpose="location"><context context-type="linenumber">282</context></context-group> </trans-unit> - <trans-unit id="_msg1113"> - <source xml:space="preserve">Unable to parse -maxuploadtarget: '%s'</source> + <trans-unit id="_msg1115"> + <source xml:space="preserve">Unable to open %s for writing</source> <context-group purpose="location"><context context-type="linenumber">283</context></context-group> </trans-unit> - <trans-unit id="_msg1114"> - <source xml:space="preserve">Unable to start HTTP server. See debug log for details.</source> + <trans-unit id="_msg1116"> + <source xml:space="preserve">Unable to parse -maxuploadtarget: '%s'</source> <context-group purpose="location"><context context-type="linenumber">284</context></context-group> </trans-unit> - <trans-unit id="_msg1115"> - <source xml:space="preserve">Unknown -blockfilterindex value %s.</source> + <trans-unit id="_msg1117"> + <source xml:space="preserve">Unable to start HTTP server. See debug log for details.</source> <context-group purpose="location"><context context-type="linenumber">285</context></context-group> </trans-unit> - <trans-unit id="_msg1116"> - <source xml:space="preserve">Unknown address type '%s'</source> + <trans-unit id="_msg1118"> + <source xml:space="preserve">Unknown -blockfilterindex value %s.</source> <context-group purpose="location"><context context-type="linenumber">286</context></context-group> </trans-unit> - <trans-unit id="_msg1117"> - <source xml:space="preserve">Unknown change type '%s'</source> + <trans-unit id="_msg1119"> + <source xml:space="preserve">Unknown address type '%s'</source> <context-group purpose="location"><context context-type="linenumber">287</context></context-group> </trans-unit> - <trans-unit id="_msg1118"> - <source xml:space="preserve">Unknown network specified in -onlynet: '%s'</source> + <trans-unit id="_msg1120"> + <source xml:space="preserve">Unknown change type '%s'</source> <context-group purpose="location"><context context-type="linenumber">288</context></context-group> </trans-unit> - <trans-unit id="_msg1119"> - <source xml:space="preserve">Unknown new rules activated (versionbit %i)</source> + <trans-unit id="_msg1121"> + <source xml:space="preserve">Unknown network specified in -onlynet: '%s'</source> <context-group purpose="location"><context context-type="linenumber">289</context></context-group> </trans-unit> - <trans-unit id="_msg1120"> - <source xml:space="preserve">Unsupported logging category %s=%s.</source> + <trans-unit id="_msg1122"> + <source xml:space="preserve">Unknown new rules activated (versionbit %i)</source> <context-group purpose="location"><context context-type="linenumber">290</context></context-group> </trans-unit> - <trans-unit id="_msg1121"> - <source xml:space="preserve">User Agent comment (%s) contains unsafe characters.</source> + <trans-unit id="_msg1123"> + <source xml:space="preserve">Unsupported logging category %s=%s.</source> <context-group purpose="location"><context context-type="linenumber">291</context></context-group> </trans-unit> - <trans-unit id="_msg1122"> - <source xml:space="preserve">Verifying blocks…</source> + <trans-unit id="_msg1124"> + <source xml:space="preserve">User Agent comment (%s) contains unsafe characters.</source> <context-group purpose="location"><context context-type="linenumber">292</context></context-group> </trans-unit> - <trans-unit id="_msg1123"> - <source xml:space="preserve">Verifying wallet(s)…</source> + <trans-unit id="_msg1125"> + <source xml:space="preserve">Verifying blocks…</source> <context-group purpose="location"><context context-type="linenumber">293</context></context-group> </trans-unit> - <trans-unit id="_msg1124"> - <source xml:space="preserve">Wallet needed to be rewritten: restart %s to complete</source> + <trans-unit id="_msg1126"> + <source xml:space="preserve">Verifying wallet(s)…</source> <context-group purpose="location"><context context-type="linenumber">294</context></context-group> </trans-unit> + <trans-unit id="_msg1127"> + <source xml:space="preserve">Wallet needed to be rewritten: restart %s to complete</source> + <context-group purpose="location"><context context-type="linenumber">295</context></context-group> + </trans-unit> </group> </body></file> </xliff> diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 8f116a05ef..f57915e805 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -2129,7 +2129,7 @@ static RPCHelpMan scantxoutset() for (const UniValue& scanobject : request.params[1].get_array().getValues()) { FlatSigningProvider provider; auto scripts = EvalDescriptorStringOrObject(scanobject, provider); - for (const auto& script : scripts) { + for (CScript& script : scripts) { std::string inferred = InferDescriptor(script, provider)->ToString(); needles.emplace(script); descriptors.emplace(std::move(script), std::move(inferred)); diff --git a/src/script/descriptor.cpp b/src/script/descriptor.cpp index 434e106dad..864eb8864f 100644 --- a/src/script/descriptor.cpp +++ b/src/script/descriptor.cpp @@ -572,7 +572,7 @@ public: if (pos++) ret += ","; std::string tmp; if (!scriptarg->ToStringHelper(arg, tmp, type, cache)) return false; - ret += std::move(tmp); + ret += tmp; } return true; } @@ -596,7 +596,7 @@ public: tmp = pubkey->ToString(); break; } - ret += std::move(tmp); + ret += tmp; } std::string subscript; if (!ToStringSubScriptHelper(arg, subscript, type, cache)) return false; @@ -612,7 +612,7 @@ public: return AddChecksum(ret); } - bool ToPrivateString(const SigningProvider& arg, std::string& out) const final + bool ToPrivateString(const SigningProvider& arg, std::string& out) const override { bool ret = ToStringHelper(&arg, out, StringType::PRIVATE); out = AddChecksum(out); @@ -698,6 +698,7 @@ public: return OutputTypeFromDestination(m_destination); } bool IsSingleType() const final { return true; } + bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; } }; /** A parsed raw(H) descriptor. */ @@ -718,6 +719,7 @@ public: return OutputTypeFromDestination(dest); } bool IsSingleType() const final { return true; } + bool ToPrivateString(const SigningProvider& arg, std::string& out) const final { return false; } }; /** A parsed pk(P) descriptor. */ @@ -912,7 +914,7 @@ protected: } std::string tmp; if (!m_subdescriptor_args[pos]->ToStringHelper(arg, tmp, type, cache)) return false; - ret += std::move(tmp); + ret += tmp; while (!path.empty() && path.back()) { if (path.size() > 1) ret += '}'; path.pop_back(); diff --git a/src/test/fuzz/txorphan.cpp b/src/test/fuzz/txorphan.cpp index 7580651371..943f3f5fdf 100644 --- a/src/test/fuzz/txorphan.cpp +++ b/src/test/fuzz/txorphan.cpp @@ -19,7 +19,6 @@ #include <util/check.h> #include <util/time.h> -#include <algorithm> #include <cstdint> #include <memory> #include <set> diff --git a/src/test/i2p_tests.cpp b/src/test/i2p_tests.cpp index 80684ac205..9da1ee11f9 100644 --- a/src/test/i2p_tests.cpp +++ b/src/test/i2p_tests.cpp @@ -3,6 +3,7 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include <i2p.h> +#include <logging.h> #include <netaddress.h> #include <test/util/logging.h> #include <test/util/net.h> @@ -19,6 +20,8 @@ BOOST_FIXTURE_TEST_SUITE(i2p_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(unlimited_recv) { + const auto prev_log_level{LogInstance().LogLevel()}; + LogInstance().SetLogLevel(BCLog::Level::Trace); auto CreateSockOrig = CreateSock; // Mock CreateSock() to create MockSock. @@ -39,6 +42,7 @@ BOOST_AUTO_TEST_CASE(unlimited_recv) } CreateSock = CreateSockOrig; + LogInstance().SetLogLevel(prev_log_level); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/logging_tests.cpp b/src/test/logging_tests.cpp index 5a5e3b3f1f..a6f3a62c71 100644 --- a/src/test/logging_tests.cpp +++ b/src/test/logging_tests.cpp @@ -2,6 +2,7 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. +#include <init/common.h> #include <logging.h> #include <logging/timer.h> #include <test/util/setup_common.h> @@ -10,6 +11,7 @@ #include <chrono> #include <fstream> #include <iostream> +#include <unordered_map> #include <utility> #include <vector> @@ -17,6 +19,12 @@ BOOST_FIXTURE_TEST_SUITE(logging_tests, BasicTestingSetup) +static void ResetLogger() +{ + LogInstance().SetLogLevel(BCLog::DEFAULT_LOG_LEVEL); + LogInstance().SetCategoryLogLevel({}); +} + struct LogSetup : public BasicTestingSetup { fs::path prev_log_path; fs::path tmp_log_path; @@ -25,6 +33,8 @@ struct LogSetup : public BasicTestingSetup { bool prev_log_timestamps; bool prev_log_threadnames; bool prev_log_sourcelocations; + std::unordered_map<BCLog::LogFlags, BCLog::Level> prev_category_levels; + BCLog::Level prev_log_level; LogSetup() : prev_log_path{LogInstance().m_file_path}, tmp_log_path{m_args.GetDataDirBase() / "tmp_debug.log"}, @@ -32,14 +42,21 @@ struct LogSetup : public BasicTestingSetup { prev_print_to_file{LogInstance().m_print_to_file}, prev_log_timestamps{LogInstance().m_log_timestamps}, prev_log_threadnames{LogInstance().m_log_threadnames}, - prev_log_sourcelocations{LogInstance().m_log_sourcelocations} + prev_log_sourcelocations{LogInstance().m_log_sourcelocations}, + prev_category_levels{LogInstance().CategoryLevels()}, + prev_log_level{LogInstance().LogLevel()} { LogInstance().m_file_path = tmp_log_path; LogInstance().m_reopen_file = true; LogInstance().m_print_to_file = true; LogInstance().m_log_timestamps = false; LogInstance().m_log_threadnames = false; - LogInstance().m_log_sourcelocations = true; + + // Prevent tests from failing when the line number of the logs changes. + LogInstance().m_log_sourcelocations = false; + + LogInstance().SetLogLevel(BCLog::Level::Debug); + LogInstance().SetCategoryLogLevel({}); } ~LogSetup() @@ -51,6 +68,8 @@ struct LogSetup : public BasicTestingSetup { LogInstance().m_log_timestamps = prev_log_timestamps; LogInstance().m_log_threadnames = prev_log_threadnames; LogInstance().m_log_sourcelocations = prev_log_sourcelocations; + LogInstance().SetLogLevel(prev_log_level); + LogInstance().SetCategoryLogLevel(prev_category_levels); } }; @@ -74,6 +93,7 @@ BOOST_AUTO_TEST_CASE(logging_timer) BOOST_FIXTURE_TEST_CASE(logging_LogPrintf_, LogSetup) { + LogInstance().m_log_sourcelocations = true; LogPrintf_("fn1", "src1", 1, BCLog::LogFlags::NET, BCLog::Level::Debug, "foo1: %s", "bar1\n"); LogPrintf_("fn2", "src2", 2, BCLog::LogFlags::NET, BCLog::Level::None, "foo2: %s", "bar2\n"); LogPrintf_("fn3", "src3", 3, BCLog::LogFlags::NONE, BCLog::Level::Debug, "foo3: %s", "bar3\n"); @@ -94,9 +114,6 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintf_, LogSetup) BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros, LogSetup) { - // Prevent tests from failing when the line number of the following log calls changes. - LogInstance().m_log_sourcelocations = false; - LogPrintf("foo5: %s\n", "bar5"); LogPrint(BCLog::NET, "foo6: %s\n", "bar6"); LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "foo7: %s\n", "bar7"); @@ -123,16 +140,14 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros, LogSetup) BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros_CategoryName, LogSetup) { - // Prevent tests from failing when the line number of the following log calls changes. - LogInstance().m_log_sourcelocations = false; LogInstance().EnableCategory(BCLog::LogFlags::ALL); - const auto concated_categery_names = LogInstance().LogCategoriesString(); + const auto concatenated_category_names = LogInstance().LogCategoriesString(); std::vector<std::pair<BCLog::LogFlags, std::string>> expected_category_names; - const auto category_names = SplitString(concated_categery_names, ','); + const auto category_names = SplitString(concatenated_category_names, ','); for (const auto& category_name : category_names) { - BCLog::LogFlags category = BCLog::NONE; + BCLog::LogFlags category; const auto trimmed_category_name = TrimString(category_name); - BOOST_TEST(GetLogCategory(category, trimmed_category_name)); + BOOST_REQUIRE(GetLogCategory(category, trimmed_category_name)); expected_category_names.emplace_back(category, trimmed_category_name); } @@ -153,4 +168,92 @@ BOOST_FIXTURE_TEST_CASE(logging_LogPrintMacros_CategoryName, LogSetup) BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end()); } +BOOST_FIXTURE_TEST_CASE(logging_SeverityLevels, LogSetup) +{ + LogInstance().EnableCategory(BCLog::LogFlags::ALL); + + LogInstance().SetLogLevel(BCLog::Level::Debug); + LogInstance().SetCategoryLogLevel(/*category_str=*/"net", /*level_str=*/"info"); + + // Global log level + LogPrintLevel(BCLog::HTTP, BCLog::Level::Info, "foo1: %s\n", "bar1"); + LogPrintLevel(BCLog::MEMPOOL, BCLog::Level::Trace, "foo2: %s. This log level is lower than the global one.\n", "bar2"); + LogPrintLevel(BCLog::VALIDATION, BCLog::Level::Warning, "foo3: %s\n", "bar3"); + LogPrintLevel(BCLog::RPC, BCLog::Level::Error, "foo4: %s\n", "bar4"); + + // Category-specific log level + LogPrintLevel(BCLog::NET, BCLog::Level::Warning, "foo5: %s\n", "bar5"); + LogPrintLevel(BCLog::NET, BCLog::Level::Debug, "foo6: %s. This log level is the same as the global one but lower than the category-specific one, which takes precedence. \n", "bar6"); + LogPrintLevel(BCLog::NET, BCLog::Level::Error, "foo7: %s\n", "bar7"); + + std::vector<std::string> expected = { + "[http:info] foo1: bar1", + "[validation:warning] foo3: bar3", + "[rpc:error] foo4: bar4", + "[net:warning] foo5: bar5", + "[net:error] foo7: bar7", + }; + std::ifstream file{tmp_log_path}; + std::vector<std::string> log_lines; + for (std::string log; std::getline(file, log);) { + log_lines.push_back(log); + } + BOOST_CHECK_EQUAL_COLLECTIONS(log_lines.begin(), log_lines.end(), expected.begin(), expected.end()); +} + +BOOST_FIXTURE_TEST_CASE(logging_Conf, LogSetup) +{ + // Set global log level + { + ResetLogger(); + ArgsManager args; + args.AddArg("-loglevel", "...", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + const char* argv_test[] = {"bitcoind", "-loglevel=debug"}; + std::string err; + BOOST_REQUIRE(args.ParseParameters(2, argv_test, err)); + init::SetLoggingLevel(args); + BOOST_CHECK_EQUAL(LogInstance().LogLevel(), BCLog::Level::Debug); + } + + // Set category-specific log level + { + ResetLogger(); + ArgsManager args; + args.AddArg("-loglevel", "...", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + const char* argv_test[] = {"bitcoind", "-loglevel=net:trace"}; + std::string err; + BOOST_REQUIRE(args.ParseParameters(2, argv_test, err)); + init::SetLoggingLevel(args); + BOOST_CHECK_EQUAL(LogInstance().LogLevel(), BCLog::DEFAULT_LOG_LEVEL); + + const auto& category_levels{LogInstance().CategoryLevels()}; + const auto net_it{category_levels.find(BCLog::LogFlags::NET)}; + BOOST_REQUIRE(net_it != category_levels.end()); + BOOST_CHECK_EQUAL(net_it->second, BCLog::Level::Trace); + } + + // Set both global log level and category-specific log level + { + ResetLogger(); + ArgsManager args; + args.AddArg("-loglevel", "...", ArgsManager::ALLOW_ANY, OptionsCategory::DEBUG_TEST); + const char* argv_test[] = {"bitcoind", "-loglevel=debug", "-loglevel=net:trace", "-loglevel=http:info"}; + std::string err; + BOOST_REQUIRE(args.ParseParameters(4, argv_test, err)); + init::SetLoggingLevel(args); + BOOST_CHECK_EQUAL(LogInstance().LogLevel(), BCLog::Level::Debug); + + const auto& category_levels{LogInstance().CategoryLevels()}; + BOOST_CHECK_EQUAL(category_levels.size(), 2); + + const auto net_it{category_levels.find(BCLog::LogFlags::NET)}; + BOOST_CHECK(net_it != category_levels.end()); + BOOST_CHECK_EQUAL(net_it->second, BCLog::Level::Trace); + + const auto http_it{category_levels.find(BCLog::LogFlags::HTTP)}; + BOOST_CHECK(http_it != category_levels.end()); + BOOST_CHECK_EQUAL(http_it->second, BCLog::Level::Info); + } +} + BOOST_AUTO_TEST_SUITE_END() diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp index 8a0b03c9d1..c3989a12fe 100644 --- a/src/test/util/setup_common.cpp +++ b/src/test/util/setup_common.cpp @@ -108,6 +108,7 @@ BasicTestingSetup::BasicTestingSetup(const std::string& chainName, const std::ve "-logsourcelocations", "-logtimemicros", "-logthreadnames", + "-loglevel=trace", "-debug", "-debugexclude=libevent", "-debugexclude=leveldb", diff --git a/src/threadinterrupt.h b/src/threadinterrupt.h index 363aab39ce..979bc2ee3e 100644 --- a/src/threadinterrupt.h +++ b/src/threadinterrupt.h @@ -6,6 +6,7 @@ #define BITCOIN_THREADINTERRUPT_H #include <sync.h> +#include <threadsafety.h> #include <atomic> #include <chrono> diff --git a/src/univalue/include/univalue.h b/src/univalue/include/univalue.h index 8ba6fd5425..ccaf56a271 100644 --- a/src/univalue/include/univalue.h +++ b/src/univalue/include/univalue.h @@ -80,14 +80,14 @@ public: bool isArray() const { return (typ == VARR); } bool isObject() const { return (typ == VOBJ); } - void push_back(const UniValue& val); + void push_back(UniValue val); void push_backV(const std::vector<UniValue>& vec); template <class It> void push_backV(It first, It last); - void __pushKV(const std::string& key, const UniValue& val); - void pushKV(const std::string& key, const UniValue& val); - void pushKVs(const UniValue& obj); + void __pushKV(std::string key, UniValue val); + void pushKV(std::string key, UniValue val); + void pushKVs(UniValue obj); std::string write(unsigned int prettyIndent = 0, unsigned int indentLevel = 0) const; diff --git a/src/univalue/lib/univalue.cpp b/src/univalue/lib/univalue.cpp index 55e777b8ae..12a434dd0e 100644 --- a/src/univalue/lib/univalue.cpp +++ b/src/univalue/lib/univalue.cpp @@ -101,11 +101,11 @@ void UniValue::setObject() typ = VOBJ; } -void UniValue::push_back(const UniValue& val_) +void UniValue::push_back(UniValue val) { checkType(VARR); - values.push_back(val_); + values.push_back(std::move(val)); } void UniValue::push_backV(const std::vector<UniValue>& vec) @@ -115,32 +115,32 @@ void UniValue::push_backV(const std::vector<UniValue>& vec) values.insert(values.end(), vec.begin(), vec.end()); } -void UniValue::__pushKV(const std::string& key, const UniValue& val_) +void UniValue::__pushKV(std::string key, UniValue val) { checkType(VOBJ); - keys.push_back(key); - values.push_back(val_); + keys.push_back(std::move(key)); + values.push_back(std::move(val)); } -void UniValue::pushKV(const std::string& key, const UniValue& val_) +void UniValue::pushKV(std::string key, UniValue val) { checkType(VOBJ); size_t idx; if (findKey(key, idx)) - values[idx] = val_; + values[idx] = std::move(val); else - __pushKV(key, val_); + __pushKV(std::move(key), std::move(val)); } -void UniValue::pushKVs(const UniValue& obj) +void UniValue::pushKVs(UniValue obj) { checkType(VOBJ); obj.checkType(VOBJ); for (size_t i = 0; i < obj.keys.size(); i++) - __pushKV(obj.keys[i], obj.values.at(i)); + __pushKV(std::move(obj.keys.at(i)), std::move(obj.values.at(i))); } void UniValue::getObjMap(std::map<std::string,UniValue>& kv) const diff --git a/src/util/bip32.cpp b/src/util/bip32.cpp index 39e43eeb31..796af4a544 100644 --- a/src/util/bip32.cpp +++ b/src/util/bip32.cpp @@ -6,12 +6,10 @@ #include <util/bip32.h> #include <util/strencodings.h> -#include <algorithm> #include <cstdint> #include <cstdio> #include <sstream> - bool ParseHDKeypath(const std::string& keypath_str, std::vector<uint32_t>& keypath) { std::stringstream ss(keypath_str); diff --git a/src/util/message.cpp b/src/util/message.cpp index 028251a5a8..7d6f3403f4 100644 --- a/src/util/message.cpp +++ b/src/util/message.cpp @@ -8,7 +8,6 @@ #include <key_io.h> #include <pubkey.h> #include <script/standard.h> -#include <serialize.h> #include <uint256.h> #include <util/message.h> #include <util/strencodings.h> diff --git a/src/util/strencodings.cpp b/src/util/strencodings.cpp index 303e19beec..b5ac151374 100644 --- a/src/util/strencodings.cpp +++ b/src/util/strencodings.cpp @@ -6,7 +6,6 @@ #include <span.h> #include <util/strencodings.h> -#include <algorithm> #include <array> #include <cassert> #include <cstring> diff --git a/src/util/string.cpp b/src/util/string.cpp index db6dbe4135..e994c85f1c 100644 --- a/src/util/string.cpp +++ b/src/util/string.cpp @@ -6,10 +6,9 @@ #include <regex> #include <string> -#include <utility> void ReplaceAll(std::string& in_out, const std::string& search, const std::string& substitute) { if (search.empty()) return; - in_out = std::regex_replace(in_out, std::regex(std::move(search)), substitute); + in_out = std::regex_replace(in_out, std::regex(search), substitute); } diff --git a/src/util/string.h b/src/util/string.h index 0bcf7d760f..9b4c9a7e28 100644 --- a/src/util/string.h +++ b/src/util/string.h @@ -7,7 +7,6 @@ #include <util/spanparsing.h> -#include <algorithm> #include <array> #include <cstdint> #include <cstring> diff --git a/src/validation.cpp b/src/validation.cpp index a2a339a5a1..3e17d4cd87 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -3718,7 +3718,7 @@ void ChainstateManager::ReportHeadersPresync(const arith_uint256& work, int64_t { LOCK(cs_main); // Don't report headers presync progress if we already have a post-minchainwork header chain. - // This means we lose reporting for potentially legimate, but unlikely, deep reorgs, but + // This means we lose reporting for potentially legitimate, but unlikely, deep reorgs, but // prevent attackers that spam low-work headers from filling our logs. if (m_best_header->nChainWork >= UintToArith256(GetConsensus().nMinimumChainWork)) return; // Rate limit headers presync updates to 4 per second, as these are not subject to DoS diff --git a/src/wallet/rpc/backup.cpp b/src/wallet/rpc/backup.cpp index 49e5b5d5e7..4c623fa1ba 100644 --- a/src/wallet/rpc/backup.cpp +++ b/src/wallet/rpc/backup.cpp @@ -1784,34 +1784,59 @@ RPCHelpMan listdescriptors() LOCK(wallet->cs_wallet); - UniValue descriptors(UniValue::VARR); const auto active_spk_mans = wallet->GetActiveScriptPubKeyMans(); + + struct WalletDescInfo { + std::string descriptor; + uint64_t creation_time; + bool active; + std::optional<bool> internal; + std::optional<std::pair<int64_t,int64_t>> range; + int64_t next_index; + }; + + std::vector<WalletDescInfo> wallet_descriptors; for (const auto& spk_man : wallet->GetAllScriptPubKeyMans()) { const auto desc_spk_man = dynamic_cast<DescriptorScriptPubKeyMan*>(spk_man); if (!desc_spk_man) { throw JSONRPCError(RPC_WALLET_ERROR, "Unexpected ScriptPubKey manager type."); } - UniValue spk(UniValue::VOBJ); LOCK(desc_spk_man->cs_desc_man); const auto& wallet_descriptor = desc_spk_man->GetWalletDescriptor(); std::string descriptor; - if (!desc_spk_man->GetDescriptorString(descriptor, priv)) { throw JSONRPCError(RPC_WALLET_ERROR, "Can't get descriptor string."); } - spk.pushKV("desc", descriptor); - spk.pushKV("timestamp", wallet_descriptor.creation_time); - spk.pushKV("active", active_spk_mans.count(desc_spk_man) != 0); - const auto internal = wallet->IsInternalScriptPubKeyMan(desc_spk_man); - if (internal.has_value()) { - spk.pushKV("internal", *internal); + const bool is_range = wallet_descriptor.descriptor->IsRange(); + wallet_descriptors.push_back({ + descriptor, + wallet_descriptor.creation_time, + active_spk_mans.count(desc_spk_man) != 0, + wallet->IsInternalScriptPubKeyMan(desc_spk_man), + is_range ? std::optional(std::make_pair(wallet_descriptor.range_start, wallet_descriptor.range_end)) : std::nullopt, + wallet_descriptor.next_index + }); + } + + std::sort(wallet_descriptors.begin(), wallet_descriptors.end(), [](const auto& a, const auto& b) { + return a.descriptor < b.descriptor; + }); + + UniValue descriptors(UniValue::VARR); + for (const WalletDescInfo& info : wallet_descriptors) { + UniValue spk(UniValue::VOBJ); + spk.pushKV("desc", info.descriptor); + spk.pushKV("timestamp", info.creation_time); + spk.pushKV("active", info.active); + if (info.internal.has_value()) { + spk.pushKV("internal", info.internal.value()); } - if (wallet_descriptor.descriptor->IsRange()) { + if (info.range.has_value()) { UniValue range(UniValue::VARR); - range.push_back(wallet_descriptor.range_start); - range.push_back(wallet_descriptor.range_end - 1); + range.push_back(info.range->first); + range.push_back(info.range->second - 1); spk.pushKV("range", range); - spk.pushKV("next", wallet_descriptor.next_index); + spk.pushKV("next", info.next_index); } descriptors.push_back(spk); } diff --git a/src/wallet/rpc/wallet.cpp b/src/wallet/rpc/wallet.cpp index eb275f9951..675c4a759d 100644 --- a/src/wallet/rpc/wallet.cpp +++ b/src/wallet/rpc/wallet.cpp @@ -701,6 +701,59 @@ RPCHelpMan simulaterawtransaction() }; } +static RPCHelpMan migratewallet() +{ + return RPCHelpMan{"migratewallet", + "EXPERIMENTAL warning: This call may not work as expected and may be changed in future releases\n" + "\nMigrate the wallet to a descriptor wallet.\n" + "A new wallet backup will need to be made.\n" + "\nThe migration process will create a backup of the wallet before migrating. This backup\n" + "file will be named <wallet name>-<timestamp>.legacy.bak and can be found in the directory\n" + "for this wallet. In the event of an incorrect migration, the backup can be restored using restorewallet." + + HELP_REQUIRING_PASSPHRASE, + {}, + RPCResult{ + RPCResult::Type::OBJ, "", "", + { + {RPCResult::Type::STR, "wallet_name", "The name of the primary migrated wallet"}, + {RPCResult::Type::STR, "watchonly_name", /*optional=*/true, "The name of the migrated wallet containing the watchonly scripts"}, + {RPCResult::Type::STR, "solvables_name", /*optional=*/true, "The name of the migrated wallet containing solvable but not watched scripts"}, + {RPCResult::Type::STR, "backup_path", "The location of the backup of the original wallet"}, + } + }, + RPCExamples{ + HelpExampleCli("migratewallet", "") + + HelpExampleRpc("migratewallet", "") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue + { + std::shared_ptr<CWallet> wallet = GetWalletForJSONRPCRequest(request); + if (!wallet) return NullUniValue; + + EnsureWalletIsUnlocked(*wallet); + + WalletContext& context = EnsureWalletContext(request.context); + + util::Result<MigrationResult> res = MigrateLegacyToDescriptor(std::move(wallet), context); + if (!res) { + throw JSONRPCError(RPC_WALLET_ERROR, util::ErrorString(res).original); + } + + UniValue r{UniValue::VOBJ}; + r.pushKV("wallet_name", res->wallet_name); + if (res->watchonly_wallet) { + r.pushKV("watchonly_name", res->watchonly_wallet->GetName()); + } + if (res->solvables_wallet) { + r.pushKV("solvables_name", res->solvables_wallet->GetName()); + } + r.pushKV("backup_path", res->backup_path.u8string()); + + return r; + }, + }; +} + // addresses RPCHelpMan getaddressinfo(); RPCHelpMan getnewaddress(); @@ -820,6 +873,7 @@ Span<const CRPCCommand> GetWalletRPCCommands() {"wallet", &listwallets}, {"wallet", &loadwallet}, {"wallet", &lockunspent}, + {"wallet", &migratewallet}, {"wallet", &newkeypool}, {"wallet", &removeprunedfunds}, {"wallet", &rescanblockchain}, diff --git a/src/wallet/scriptpubkeyman.cpp b/src/wallet/scriptpubkeyman.cpp index 40d5ecd755..41654579c6 100644 --- a/src/wallet/scriptpubkeyman.cpp +++ b/src/wallet/scriptpubkeyman.cpp @@ -999,9 +999,10 @@ bool LegacyScriptPubKeyMan::GetKeyOrigin(const CKeyID& keyID, KeyOriginInfo& inf { LOCK(cs_KeyStore); auto it = mapKeyMetadata.find(keyID); - if (it != mapKeyMetadata.end()) { - meta = it->second; + if (it == mapKeyMetadata.end()) { + return false; } + meta = it->second; } if (meta.has_key_origin) { std::copy(meta.key_origin.fingerprint, meta.key_origin.fingerprint + 4, info.fingerprint); @@ -1658,6 +1659,318 @@ std::set<CKeyID> LegacyScriptPubKeyMan::GetKeys() const return set_address; } +const std::unordered_set<CScript, SaltedSipHasher> LegacyScriptPubKeyMan::GetScriptPubKeys() const +{ + LOCK(cs_KeyStore); + std::unordered_set<CScript, SaltedSipHasher> spks; + + // All keys have at least P2PK and P2PKH + for (const auto& key_pair : mapKeys) { + const CPubKey& pub = key_pair.second.GetPubKey(); + spks.insert(GetScriptForRawPubKey(pub)); + spks.insert(GetScriptForDestination(PKHash(pub))); + } + for (const auto& key_pair : mapCryptedKeys) { + const CPubKey& pub = key_pair.second.first; + spks.insert(GetScriptForRawPubKey(pub)); + spks.insert(GetScriptForDestination(PKHash(pub))); + } + + // For every script in mapScript, only the ISMINE_SPENDABLE ones are being tracked. + // The watchonly ones will be in setWatchOnly which we deal with later + // For all keys, if they have segwit scripts, those scripts will end up in mapScripts + for (const auto& script_pair : mapScripts) { + const CScript& script = script_pair.second; + if (IsMine(script) == ISMINE_SPENDABLE) { + // Add ScriptHash for scripts that are not already P2SH + if (!script.IsPayToScriptHash()) { + spks.insert(GetScriptForDestination(ScriptHash(script))); + } + // For segwit scripts, we only consider them spendable if we have the segwit spk + int wit_ver = -1; + std::vector<unsigned char> witprog; + if (script.IsWitnessProgram(wit_ver, witprog) && wit_ver == 0) { + spks.insert(script); + } + } else { + // Multisigs are special. They don't show up as ISMINE_SPENDABLE unless they are in a P2SH + // So check the P2SH of a multisig to see if we should insert it + std::vector<std::vector<unsigned char>> sols; + TxoutType type = Solver(script, sols); + if (type == TxoutType::MULTISIG) { + CScript ms_spk = GetScriptForDestination(ScriptHash(script)); + if (IsMine(ms_spk) != ISMINE_NO) { + spks.insert(ms_spk); + } + } + } + } + + // All watchonly scripts are raw + spks.insert(setWatchOnly.begin(), setWatchOnly.end()); + + return spks; +} + +std::optional<MigrationData> LegacyScriptPubKeyMan::MigrateToDescriptor() +{ + LOCK(cs_KeyStore); + if (m_storage.IsLocked()) { + return std::nullopt; + } + + MigrationData out; + + std::unordered_set<CScript, SaltedSipHasher> spks{GetScriptPubKeys()}; + + // Get all key ids + std::set<CKeyID> keyids; + for (const auto& key_pair : mapKeys) { + keyids.insert(key_pair.first); + } + for (const auto& key_pair : mapCryptedKeys) { + keyids.insert(key_pair.first); + } + + // Get key metadata and figure out which keys don't have a seed + // Note that we do not ignore the seeds themselves because they are considered IsMine! + for (auto keyid_it = keyids.begin(); keyid_it != keyids.end();) { + const CKeyID& keyid = *keyid_it; + const auto& it = mapKeyMetadata.find(keyid); + if (it != mapKeyMetadata.end()) { + const CKeyMetadata& meta = it->second; + if (meta.hdKeypath == "s" || meta.hdKeypath == "m") { + keyid_it++; + continue; + } + if (m_hd_chain.seed_id == meta.hd_seed_id || m_inactive_hd_chains.count(meta.hd_seed_id) > 0) { + keyid_it = keyids.erase(keyid_it); + continue; + } + } + keyid_it++; + } + + // keyids is now all non-HD keys. Each key will have its own combo descriptor + for (const CKeyID& keyid : keyids) { + CKey key; + if (!GetKey(keyid, key)) { + assert(false); + } + + // Get birthdate from key meta + uint64_t creation_time = 0; + const auto& it = mapKeyMetadata.find(keyid); + if (it != mapKeyMetadata.end()) { + creation_time = it->second.nCreateTime; + } + + // Get the key origin + // Maybe this doesn't matter because floating keys here shouldn't have origins + KeyOriginInfo info; + bool has_info = GetKeyOrigin(keyid, info); + std::string origin_str = has_info ? "[" + HexStr(info.fingerprint) + FormatHDKeypath(info.path) + "]" : ""; + + // Construct the combo descriptor + std::string desc_str = "combo(" + origin_str + HexStr(key.GetPubKey()) + ")"; + FlatSigningProvider keys; + std::string error; + std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, error, false); + WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0); + + // Make the DescriptorScriptPubKeyMan and get the scriptPubKeys + auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc)); + desc_spk_man->AddDescriptorKey(key, key.GetPubKey()); + desc_spk_man->TopUp(); + auto desc_spks = desc_spk_man->GetScriptPubKeys(); + + // Remove the scriptPubKeys from our current set + for (const CScript& spk : desc_spks) { + size_t erased = spks.erase(spk); + assert(erased == 1); + assert(IsMine(spk) == ISMINE_SPENDABLE); + } + + out.desc_spkms.push_back(std::move(desc_spk_man)); + } + + // Handle HD keys by using the CHDChains + std::vector<CHDChain> chains; + chains.push_back(m_hd_chain); + for (const auto& chain_pair : m_inactive_hd_chains) { + chains.push_back(chain_pair.second); + } + for (const CHDChain& chain : chains) { + for (int i = 0; i < 2; ++i) { + // Skip if doing internal chain and split chain is not supported + if (chain.seed_id.IsNull() || (i == 1 && !m_storage.CanSupportFeature(FEATURE_HD_SPLIT))) { + continue; + } + // Get the master xprv + CKey seed_key; + if (!GetKey(chain.seed_id, seed_key)) { + assert(false); + } + CExtKey master_key; + master_key.SetSeed(seed_key); + + // Make the combo descriptor + std::string xpub = EncodeExtPubKey(master_key.Neuter()); + std::string desc_str = "combo(" + xpub + "/0'/" + ToString(i) + "'/*')"; + FlatSigningProvider keys; + std::string error; + std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, error, false); + uint32_t chain_counter = std::max((i == 1 ? chain.nInternalChainCounter : chain.nExternalChainCounter), (uint32_t)0); + WalletDescriptor w_desc(std::move(desc), 0, 0, chain_counter, 0); + + // Make the DescriptorScriptPubKeyMan and get the scriptPubKeys + auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc)); + desc_spk_man->AddDescriptorKey(master_key.key, master_key.key.GetPubKey()); + desc_spk_man->TopUp(); + auto desc_spks = desc_spk_man->GetScriptPubKeys(); + + // Remove the scriptPubKeys from our current set + for (const CScript& spk : desc_spks) { + size_t erased = spks.erase(spk); + assert(erased == 1); + assert(IsMine(spk) == ISMINE_SPENDABLE); + } + + out.desc_spkms.push_back(std::move(desc_spk_man)); + } + } + // Add the current master seed to the migration data + if (!m_hd_chain.seed_id.IsNull()) { + CKey seed_key; + if (!GetKey(m_hd_chain.seed_id, seed_key)) { + assert(false); + } + out.master_key.SetSeed(seed_key); + } + + // Handle the rest of the scriptPubKeys which must be imports and may not have all info + for (auto it = spks.begin(); it != spks.end();) { + const CScript& spk = *it; + + // Get birthdate from script meta + uint64_t creation_time = 0; + const auto& mit = m_script_metadata.find(CScriptID(spk)); + if (mit != m_script_metadata.end()) { + creation_time = mit->second.nCreateTime; + } + + // InferDescriptor as that will get us all the solving info if it is there + std::unique_ptr<Descriptor> desc = InferDescriptor(spk, *GetSolvingProvider(spk)); + // Get the private keys for this descriptor + std::vector<CScript> scripts; + FlatSigningProvider keys; + if (!desc->Expand(0, DUMMY_SIGNING_PROVIDER, scripts, keys)) { + assert(false); + } + std::set<CKeyID> privkeyids; + for (const auto& key_orig_pair : keys.origins) { + privkeyids.insert(key_orig_pair.first); + } + + std::vector<CScript> desc_spks; + + // Make the descriptor string with private keys + std::string desc_str; + bool watchonly = !desc->ToPrivateString(*this, desc_str); + if (watchonly && !m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { + out.watch_descs.push_back({desc->ToString(), creation_time}); + + // Get the scriptPubKeys without writing this to the wallet + FlatSigningProvider provider; + desc->Expand(0, provider, desc_spks, provider); + } else { + // Make the DescriptorScriptPubKeyMan and get the scriptPubKeys + WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0); + auto desc_spk_man = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(m_storage, w_desc)); + for (const auto& keyid : privkeyids) { + CKey key; + if (!GetKey(keyid, key)) { + continue; + } + desc_spk_man->AddDescriptorKey(key, key.GetPubKey()); + } + desc_spk_man->TopUp(); + auto desc_spks_set = desc_spk_man->GetScriptPubKeys(); + desc_spks.insert(desc_spks.end(), desc_spks_set.begin(), desc_spks_set.end()); + + out.desc_spkms.push_back(std::move(desc_spk_man)); + } + + // Remove the scriptPubKeys from our current set + for (const CScript& desc_spk : desc_spks) { + auto del_it = spks.find(desc_spk); + assert(del_it != spks.end()); + assert(IsMine(desc_spk) != ISMINE_NO); + it = spks.erase(del_it); + } + } + + // Multisigs are special. They don't show up as ISMINE_SPENDABLE unless they are in a P2SH + // So we have to check if any of our scripts are a multisig and if so, add the P2SH + for (const auto& script_pair : mapScripts) { + const CScript script = script_pair.second; + + // Get birthdate from script meta + uint64_t creation_time = 0; + const auto& it = m_script_metadata.find(CScriptID(script)); + if (it != m_script_metadata.end()) { + creation_time = it->second.nCreateTime; + } + + std::vector<std::vector<unsigned char>> sols; + TxoutType type = Solver(script, sols); + if (type == TxoutType::MULTISIG) { + CScript sh_spk = GetScriptForDestination(ScriptHash(script)); + CTxDestination witdest = WitnessV0ScriptHash(script); + CScript witprog = GetScriptForDestination(witdest); + CScript sh_wsh_spk = GetScriptForDestination(ScriptHash(witprog)); + + // We only want the multisigs that we have not already seen, i.e. they are not watchonly and not spendable + // For P2SH, a multisig is not ISMINE_NO when: + // * All keys are in the wallet + // * The multisig itself is watch only + // * The P2SH is watch only + // For P2SH-P2WSH, if the script is in the wallet, then it will have the same conditions as P2SH. + // For P2WSH, a multisig is not ISMINE_NO when, other than the P2SH conditions: + // * The P2WSH script is in the wallet and it is being watched + std::vector<std::vector<unsigned char>> keys(sols.begin() + 1, sols.begin() + sols.size() - 1); + if (HaveWatchOnly(sh_spk) || HaveWatchOnly(script) || HaveKeys(keys, *this) || (HaveCScript(CScriptID(witprog)) && HaveWatchOnly(witprog))) { + // The above emulates IsMine for these 3 scriptPubKeys, so double check that by running IsMine + assert(IsMine(sh_spk) != ISMINE_NO || IsMine(witprog) != ISMINE_NO || IsMine(sh_wsh_spk) != ISMINE_NO); + continue; + } + assert(IsMine(sh_spk) == ISMINE_NO && IsMine(witprog) == ISMINE_NO && IsMine(sh_wsh_spk) == ISMINE_NO); + + std::unique_ptr<Descriptor> sh_desc = InferDescriptor(sh_spk, *GetSolvingProvider(sh_spk)); + out.solvable_descs.push_back({sh_desc->ToString(), creation_time}); + + const auto desc = InferDescriptor(witprog, *this); + if (desc->IsSolvable()) { + std::unique_ptr<Descriptor> wsh_desc = InferDescriptor(witprog, *GetSolvingProvider(witprog)); + out.solvable_descs.push_back({wsh_desc->ToString(), creation_time}); + std::unique_ptr<Descriptor> sh_wsh_desc = InferDescriptor(sh_wsh_spk, *GetSolvingProvider(sh_wsh_spk)); + out.solvable_descs.push_back({sh_wsh_desc->ToString(), creation_time}); + } + } + } + + // Make sure that we have accounted for all scriptPubKeys + assert(spks.size() == 0); + return out; +} + +bool LegacyScriptPubKeyMan::DeleteRecords() +{ + LOCK(cs_KeyStore); + WalletBatch batch(m_storage.GetDatabase()); + return batch.EraseRecords(DBKeys::LEGACY_TYPES); +} + util::Result<CTxDestination> DescriptorScriptPubKeyMan::GetNewDestination(const OutputType type) { // Returns true if this descriptor supports getting new addresses. Conditions where we may be unable to fetch them (e.g. locked) are caught later @@ -2327,14 +2640,14 @@ const WalletDescriptor DescriptorScriptPubKeyMan::GetWalletDescriptor() const return m_wallet_descriptor; } -const std::vector<CScript> DescriptorScriptPubKeyMan::GetScriptPubKeys() const +const std::unordered_set<CScript, SaltedSipHasher> DescriptorScriptPubKeyMan::GetScriptPubKeys() const { LOCK(cs_desc_man); - std::vector<CScript> script_pub_keys; + std::unordered_set<CScript, SaltedSipHasher> script_pub_keys; script_pub_keys.reserve(m_map_script_pub_keys.size()); for (auto const& script_pub_key: m_map_script_pub_keys) { - script_pub_keys.push_back(script_pub_key.first); + script_pub_keys.insert(script_pub_key.first); } return script_pub_keys; } diff --git a/src/wallet/scriptpubkeyman.h b/src/wallet/scriptpubkeyman.h index 408d162eba..3ab489c374 100644 --- a/src/wallet/scriptpubkeyman.h +++ b/src/wallet/scriptpubkeyman.h @@ -242,6 +242,9 @@ public: virtual uint256 GetID() const { return uint256(); } + /** Returns a set of all the scriptPubKeys that this ScriptPubKeyMan watches */ + virtual const std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const { return {}; }; + /** Prepends the wallet name in logging output to ease debugging in multi-wallet use cases */ template<typename... Params> void WalletLogPrintf(std::string fmt, Params... parameters) const { @@ -262,6 +265,8 @@ static const std::unordered_set<OutputType> LEGACY_OUTPUT_TYPES { OutputType::BECH32, }; +class DescriptorScriptPubKeyMan; + class LegacyScriptPubKeyMan : public ScriptPubKeyMan, public FillableSigningProvider { private: @@ -507,6 +512,13 @@ public: const std::map<CKeyID, int64_t>& GetAllReserveKeys() const { return m_pool_key_to_index; } std::set<CKeyID> GetKeys() const override; + const std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override; + + /** Get the DescriptorScriptPubKeyMans (with private keys) that have the same scriptPubKeys as this LegacyScriptPubKeyMan. + * Does not modify this ScriptPubKeyMan. */ + std::optional<MigrationData> MigrateToDescriptor(); + /** Delete all the records ofthis LegacyScriptPubKeyMan from disk*/ + bool DeleteRecords(); }; /** Wraps a LegacyScriptPubKeyMan so that it can be returned in a new unique_ptr. Does not provide privkeys */ @@ -630,7 +642,7 @@ public: void WriteDescriptor(); const WalletDescriptor GetWalletDescriptor() const EXCLUSIVE_LOCKS_REQUIRED(cs_desc_man); - const std::vector<CScript> GetScriptPubKeys() const; + const std::unordered_set<CScript, SaltedSipHasher> GetScriptPubKeys() const override; bool GetDescriptorString(std::string& out, const bool priv) const; diff --git a/src/wallet/spend.cpp b/src/wallet/spend.cpp index 92cf771358..d84310c323 100644 --- a/src/wallet/spend.cpp +++ b/src/wallet/spend.cpp @@ -353,7 +353,7 @@ std::map<CTxDestination, std::vector<COutput>> ListCoins(const CWallet& wallet) std::map<CTxDestination, std::vector<COutput>> result; - for (const COutput& coin : AvailableCoinsListUnspent(wallet).All()) { + for (COutput& coin : AvailableCoinsListUnspent(wallet).All()) { CTxDestination address; if ((coin.spendable || (wallet.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS) && coin.solvable)) && ExtractDestination(FindNonChangeParentOutput(wallet, coin.outpoint).scriptPubKey, address)) { diff --git a/src/wallet/test/ismine_tests.cpp b/src/wallet/test/ismine_tests.cpp index dd5cd0af46..68146eb079 100644 --- a/src/wallet/test/ismine_tests.cpp +++ b/src/wallet/test/ismine_tests.cpp @@ -43,11 +43,13 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore does not have key result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has key BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // P2PK uncompressed @@ -60,11 +62,13 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore does not have key result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has key BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // P2PKH compressed @@ -77,11 +81,13 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore does not have key result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has key BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // P2PKH uncompressed @@ -94,11 +100,13 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore does not have key result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has key BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // P2SH @@ -113,16 +121,19 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore does not have redeemScript or key result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has redeemScript but no key BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(redeemScript)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has redeemScript and key BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // (P2PKH inside) P2SH inside P2SH (invalid) @@ -141,6 +152,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // (P2PKH inside) P2SH inside P2WSH (invalid) @@ -159,6 +171,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // P2WPKH inside P2WSH (invalid) @@ -175,6 +188,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // (P2PKH inside) P2WSH inside P2WSH (invalid) @@ -193,6 +207,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // P2WPKH compressed @@ -208,6 +223,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(scriptPubKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // P2WPKH uncompressed @@ -222,11 +238,13 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore has key, but no P2SH redeemScript result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has key and P2SH redeemScript BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(scriptPubKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // scriptPubKey multisig @@ -240,24 +258,28 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore does not have any keys result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has 1/2 keys BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(uncompressedKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has 2/2 keys BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has 2/2 keys and the script BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(scriptPubKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // P2SH multisig @@ -274,11 +296,13 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore has no redeemScript result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has redeemScript BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(redeemScript)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // P2WSH multisig with compressed keys @@ -295,16 +319,19 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore has keys, but no witnessScript or P2SH redeemScript result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has keys and witnessScript, but no P2SH redeemScript BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(witnessScript)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has keys, witnessScript, P2SH redeemScript BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(scriptPubKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // P2WSH multisig with uncompressed key @@ -321,16 +348,19 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore has keys, but no witnessScript or P2SH redeemScript result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has keys and witnessScript, but no P2SH redeemScript BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(witnessScript)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has keys, witnessScript, P2SH redeemScript BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(scriptPubKey)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // P2WSH multisig wrapped in P2SH @@ -346,18 +376,21 @@ BOOST_AUTO_TEST_CASE(ismine_standard) // Keystore has no witnessScript, P2SH redeemScript, or keys result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has witnessScript and P2SH redeemScript, but no keys BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(redeemScript)); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddCScript(witnessScript)); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); // Keystore has keys, witnessScript, P2SH redeemScript BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[0])); BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->AddKey(keys[1])); result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_SPENDABLE); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 1); } // OP_RETURN @@ -372,6 +405,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // witness unspendable @@ -386,6 +420,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // witness unknown @@ -400,6 +435,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } // Nonstandard @@ -414,6 +450,7 @@ BOOST_AUTO_TEST_CASE(ismine_standard) result = keystore.GetLegacyScriptPubKeyMan()->IsMine(scriptPubKey); BOOST_CHECK_EQUAL(result, ISMINE_NO); + BOOST_CHECK(keystore.GetLegacyScriptPubKeyMan()->GetScriptPubKeys().count(scriptPubKey) == 0); } } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 69a151d5c8..b25488f6a1 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3434,6 +3434,29 @@ void CWallet::LoadDescriptorScriptPubKeyMan(uint256 id, WalletDescriptor& desc) } } +void CWallet::SetupDescriptorScriptPubKeyMans(const CExtKey& master_key) +{ + AssertLockHeld(cs_wallet); + + for (bool internal : {false, true}) { + for (OutputType t : OUTPUT_TYPES) { + auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this)); + if (IsCrypted()) { + if (IsLocked()) { + throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors"); + } + if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey, nullptr)) { + throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors"); + } + } + spk_manager->SetupDescriptorGeneration(master_key, t, internal); + uint256 id = spk_manager->GetID(); + m_spk_managers[id] = std::move(spk_manager); + AddActiveScriptPubKeyMan(id, t, internal); + } + } +} + void CWallet::SetupDescriptorScriptPubKeyMans() { AssertLockHeld(cs_wallet); @@ -3449,23 +3472,7 @@ void CWallet::SetupDescriptorScriptPubKeyMans() CExtKey master_key; master_key.SetSeed(seed_key); - for (bool internal : {false, true}) { - for (OutputType t : OUTPUT_TYPES) { - auto spk_manager = std::unique_ptr<DescriptorScriptPubKeyMan>(new DescriptorScriptPubKeyMan(*this)); - if (IsCrypted()) { - if (IsLocked()) { - throw std::runtime_error(std::string(__func__) + ": Wallet is locked, cannot setup new descriptors"); - } - if (!spk_manager->CheckDecryptionKey(vMasterKey) && !spk_manager->Encrypt(vMasterKey, nullptr)) { - throw std::runtime_error(std::string(__func__) + ": Could not encrypt new descriptors"); - } - } - spk_manager->SetupDescriptorGeneration(master_key, t, internal); - uint256 id = spk_manager->GetID(); - m_spk_managers[id] = std::move(spk_manager); - AddActiveScriptPubKeyMan(id, t, internal); - } - } + SetupDescriptorScriptPubKeyMans(master_key); } else { ExternalSigner signer = ExternalSignerScriptPubKeyMan::GetExternalSigner(); @@ -3633,9 +3640,13 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat return nullptr; } - CTxDestination dest; - if (!internal && ExtractDestination(script_pub_keys.at(0), dest)) { - SetAddressBook(dest, label, "receive"); + if (!internal) { + for (const auto& script : script_pub_keys) { + CTxDestination dest; + if (ExtractDestination(script, dest)) { + SetAddressBook(dest, label, "receive"); + } + } } } @@ -3644,4 +3655,472 @@ ScriptPubKeyMan* CWallet::AddWalletDescriptor(WalletDescriptor& desc, const Flat return spk_man; } + +bool CWallet::MigrateToSQLite(bilingual_str& error) +{ + AssertLockHeld(cs_wallet); + + WalletLogPrintf("Migrating wallet storage database from BerkeleyDB to SQLite.\n"); + + if (m_database->Format() == "sqlite") { + error = _("Error: This wallet already uses SQLite"); + return false; + } + + // Get all of the records for DB type migration + std::unique_ptr<DatabaseBatch> batch = m_database->MakeBatch(); + std::vector<std::pair<SerializeData, SerializeData>> records; + if (!batch->StartCursor()) { + error = _("Error: Unable to begin reading all records in the database"); + return false; + } + bool complete = false; + while (true) { + CDataStream ss_key(SER_DISK, CLIENT_VERSION); + CDataStream ss_value(SER_DISK, CLIENT_VERSION); + bool ret = batch->ReadAtCursor(ss_key, ss_value, complete); + if (!ret) { + break; + } + SerializeData key(ss_key.begin(), ss_key.end()); + SerializeData value(ss_value.begin(), ss_value.end()); + records.emplace_back(key, value); + } + batch->CloseCursor(); + batch.reset(); + if (!complete) { + error = _("Error: Unable to read all records in the database"); + return false; + } + + // Close this database and delete the file + fs::path db_path = fs::PathFromString(m_database->Filename()); + fs::path db_dir = db_path.parent_path(); + m_database->Close(); + fs::remove(db_path); + + // Make new DB + DatabaseOptions opts; + opts.require_create = true; + opts.require_format = DatabaseFormat::SQLITE; + DatabaseStatus db_status; + std::unique_ptr<WalletDatabase> new_db = MakeDatabase(db_dir, opts, db_status, error); + assert(new_db); // This is to prevent doing anything further with this wallet. The original file was deleted, but a backup exists. + m_database.reset(); + m_database = std::move(new_db); + + // Write existing records into the new DB + batch = m_database->MakeBatch(); + bool began = batch->TxnBegin(); + assert(began); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution. + for (const auto& [key, value] : records) { + CDataStream ss_key(key, SER_DISK, CLIENT_VERSION); + CDataStream ss_value(value, SER_DISK, CLIENT_VERSION); + if (!batch->Write(ss_key, ss_value)) { + batch->TxnAbort(); + m_database->Close(); + fs::remove(m_database->Filename()); + assert(false); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution. + } + } + bool committed = batch->TxnCommit(); + assert(committed); // This is a critical error, the new db could not be written to. The original db exists as a backup, but we should not continue execution. + return true; +} + +std::optional<MigrationData> CWallet::GetDescriptorsForLegacy(bilingual_str& error) const +{ + AssertLockHeld(cs_wallet); + + LegacyScriptPubKeyMan* legacy_spkm = GetLegacyScriptPubKeyMan(); + if (!legacy_spkm) { + error = _("Error: This wallet is already a descriptor wallet"); + return std::nullopt; + } + + std::optional<MigrationData> res = legacy_spkm->MigrateToDescriptor(); + if (res == std::nullopt) { + error = _("Error: Unable to produce descriptors for this legacy wallet. Make sure the wallet is unlocked first"); + return std::nullopt; + } + return res; +} + +bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error) +{ + AssertLockHeld(cs_wallet); + + LegacyScriptPubKeyMan* legacy_spkm = GetLegacyScriptPubKeyMan(); + if (!legacy_spkm) { + error = _("Error: This wallet is already a descriptor wallet"); + return false; + } + + for (auto& desc_spkm : data.desc_spkms) { + if (m_spk_managers.count(desc_spkm->GetID()) > 0) { + error = _("Error: Duplicate descriptors created during migration. Your wallet may be corrupted."); + return false; + } + m_spk_managers[desc_spkm->GetID()] = std::move(desc_spkm); + } + + // Remove the LegacyScriptPubKeyMan from disk + if (!legacy_spkm->DeleteRecords()) { + return false; + } + + // Remove the LegacyScriptPubKeyMan from memory + m_spk_managers.erase(legacy_spkm->GetID()); + m_external_spk_managers.clear(); + m_internal_spk_managers.clear(); + + // Setup new descriptors + SetWalletFlag(WALLET_FLAG_DESCRIPTORS); + if (!IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS)) { + // Use the existing master key if we have it + if (data.master_key.key.IsValid()) { + SetupDescriptorScriptPubKeyMans(data.master_key); + } else { + // Setup with a new seed if we don't. + SetupDescriptorScriptPubKeyMans(); + } + } + + // Check if the transactions in the wallet are still ours. Either they belong here, or they belong in the watchonly wallet. + // We need to go through these in the tx insertion order so that lookups to spends works. + std::vector<uint256> txids_to_delete; + for (const auto& [_pos, wtx] : wtxOrdered) { + if (!IsMine(*wtx->tx) && !IsFromMe(*wtx->tx)) { + // Check it is the watchonly wallet's + // solvable_wallet doesn't need to be checked because transactions for those scripts weren't being watched for + if (data.watchonly_wallet) { + LOCK(data.watchonly_wallet->cs_wallet); + if (data.watchonly_wallet->IsMine(*wtx->tx) || data.watchonly_wallet->IsFromMe(*wtx->tx)) { + // Add to watchonly wallet + if (!data.watchonly_wallet->AddToWallet(wtx->tx, wtx->m_state)) { + error = _("Error: Could not add watchonly tx to watchonly wallet"); + return false; + } + // Mark as to remove from this wallet + txids_to_delete.push_back(wtx->GetHash()); + continue; + } + } + // Both not ours and not in the watchonly wallet + error = strprintf(_("Error: Transaction %s in wallet cannot be identified to belong to migrated wallets"), wtx->GetHash().GetHex()); + return false; + } + } + // Do the removes + if (txids_to_delete.size() > 0) { + std::vector<uint256> deleted_txids; + if (ZapSelectTx(txids_to_delete, deleted_txids) != DBErrors::LOAD_OK) { + error = _("Error: Could not delete watchonly transactions"); + return false; + } + if (deleted_txids != txids_to_delete) { + error = _("Error: Not all watchonly txs could be deleted"); + return false; + } + // Tell the GUI of each tx + for (const uint256& txid : deleted_txids) { + NotifyTransactionChanged(txid, CT_UPDATED); + } + } + + // Check the address book data in the same way we did for transactions + std::vector<CTxDestination> dests_to_delete; + for (const auto& addr_pair : m_address_book) { + // Labels applied to receiving addresses should go based on IsMine + if (addr_pair.second.purpose == "receive") { + if (!IsMine(addr_pair.first)) { + // Check the address book data is the watchonly wallet's + if (data.watchonly_wallet) { + LOCK(data.watchonly_wallet->cs_wallet); + if (data.watchonly_wallet->IsMine(addr_pair.first)) { + // Add to the watchonly. Preserve the labels, purpose, and change-ness + std::string label = addr_pair.second.GetLabel(); + std::string purpose = addr_pair.second.purpose; + if (!purpose.empty()) { + data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose; + } + if (!addr_pair.second.IsChange()) { + data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label); + } + dests_to_delete.push_back(addr_pair.first); + continue; + } + } + if (data.solvable_wallet) { + LOCK(data.solvable_wallet->cs_wallet); + if (data.solvable_wallet->IsMine(addr_pair.first)) { + // Add to the solvable. Preserve the labels, purpose, and change-ness + std::string label = addr_pair.second.GetLabel(); + std::string purpose = addr_pair.second.purpose; + if (!purpose.empty()) { + data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose; + } + if (!addr_pair.second.IsChange()) { + data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label); + } + dests_to_delete.push_back(addr_pair.first); + continue; + } + } + // Not ours, not in watchonly wallet, and not in solvable + error = _("Error: Address book data in wallet cannot be identified to belong to migrated wallets"); + return false; + } + } else { + // Labels for everything else (send) should be cloned to all + if (data.watchonly_wallet) { + LOCK(data.watchonly_wallet->cs_wallet); + // Add to the watchonly. Preserve the labels, purpose, and change-ness + std::string label = addr_pair.second.GetLabel(); + std::string purpose = addr_pair.second.purpose; + if (!purpose.empty()) { + data.watchonly_wallet->m_address_book[addr_pair.first].purpose = purpose; + } + if (!addr_pair.second.IsChange()) { + data.watchonly_wallet->m_address_book[addr_pair.first].SetLabel(label); + } + continue; + } + if (data.solvable_wallet) { + LOCK(data.solvable_wallet->cs_wallet); + // Add to the solvable. Preserve the labels, purpose, and change-ness + std::string label = addr_pair.second.GetLabel(); + std::string purpose = addr_pair.second.purpose; + if (!purpose.empty()) { + data.solvable_wallet->m_address_book[addr_pair.first].purpose = purpose; + } + if (!addr_pair.second.IsChange()) { + data.solvable_wallet->m_address_book[addr_pair.first].SetLabel(label); + } + continue; + } + } + } + // Remove the things to delete + if (dests_to_delete.size() > 0) { + for (const auto& dest : dests_to_delete) { + if (!DelAddressBook(dest)) { + error = _("Error: Unable to remove watchonly address book data"); + return false; + } + } + } + + // Connect the SPKM signals + ConnectScriptPubKeyManNotifiers(); + NotifyCanGetAddressesChanged(); + + WalletLogPrintf("Wallet migration complete.\n"); + + return true; +} + +bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error, MigrationResult& res) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet) +{ + AssertLockHeld(wallet.cs_wallet); + + // Get all of the descriptors from the legacy wallet + std::optional<MigrationData> data = wallet.GetDescriptorsForLegacy(error); + if (data == std::nullopt) return false; + + // Create the watchonly and solvable wallets if necessary + if (data->watch_descs.size() > 0 || data->solvable_descs.size() > 0) { + DatabaseOptions options; + options.require_existing = false; + options.require_create = true; + + // Make the wallets + options.create_flags = WALLET_FLAG_DISABLE_PRIVATE_KEYS | WALLET_FLAG_BLANK_WALLET | WALLET_FLAG_DESCRIPTORS; + if (wallet.IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE)) { + options.create_flags |= WALLET_FLAG_AVOID_REUSE; + } + if (wallet.IsWalletFlagSet(WALLET_FLAG_KEY_ORIGIN_METADATA)) { + options.create_flags |= WALLET_FLAG_KEY_ORIGIN_METADATA; + } + if (data->watch_descs.size() > 0) { + wallet.WalletLogPrintf("Making a new watchonly wallet containing the watched scripts\n"); + + DatabaseStatus status; + std::vector<bilingual_str> warnings; + std::string wallet_name = wallet.GetName() + "_watchonly"; + data->watchonly_wallet = CreateWallet(context, wallet_name, std::nullopt, options, status, error, warnings); + if (status != DatabaseStatus::SUCCESS) { + error = _("Error: Failed to create new watchonly wallet"); + return false; + } + res.watchonly_wallet = data->watchonly_wallet; + LOCK(data->watchonly_wallet->cs_wallet); + + // Parse the descriptors and add them to the new wallet + for (const auto& [desc_str, creation_time] : data->watch_descs) { + // Parse the descriptor + FlatSigningProvider keys; + std::string parse_err; + std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, parse_err, /* require_checksum */ true); + assert(desc); // It shouldn't be possible to have the LegacyScriptPubKeyMan make an invalid descriptor + assert(!desc->IsRange()); // It shouldn't be possible to have LegacyScriptPubKeyMan make a ranged watchonly descriptor + + // Add to the wallet + WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0); + data->watchonly_wallet->AddWalletDescriptor(w_desc, keys, "", false); + } + + // Add the wallet to settings + UpdateWalletSetting(*context.chain, wallet_name, /*load_on_startup=*/true, warnings); + } + if (data->solvable_descs.size() > 0) { + wallet.WalletLogPrintf("Making a new watchonly wallet containing the unwatched solvable scripts\n"); + + DatabaseStatus status; + std::vector<bilingual_str> warnings; + std::string wallet_name = wallet.GetName() + "_solvables"; + data->solvable_wallet = CreateWallet(context, wallet_name, std::nullopt, options, status, error, warnings); + if (status != DatabaseStatus::SUCCESS) { + error = _("Error: Failed to create new watchonly wallet"); + return false; + } + res.solvables_wallet = data->solvable_wallet; + LOCK(data->solvable_wallet->cs_wallet); + + // Parse the descriptors and add them to the new wallet + for (const auto& [desc_str, creation_time] : data->solvable_descs) { + // Parse the descriptor + FlatSigningProvider keys; + std::string parse_err; + std::unique_ptr<Descriptor> desc = Parse(desc_str, keys, parse_err, /* require_checksum */ true); + assert(desc); // It shouldn't be possible to have the LegacyScriptPubKeyMan make an invalid descriptor + assert(!desc->IsRange()); // It shouldn't be possible to have LegacyScriptPubKeyMan make a ranged watchonly descriptor + + // Add to the wallet + WalletDescriptor w_desc(std::move(desc), creation_time, 0, 0, 0); + data->solvable_wallet->AddWalletDescriptor(w_desc, keys, "", false); + } + + // Add the wallet to settings + UpdateWalletSetting(*context.chain, wallet_name, /*load_on_startup=*/true, warnings); + } + } + + // Add the descriptors to wallet, remove LegacyScriptPubKeyMan, and cleanup txs and address book data + if (!wallet.ApplyMigrationData(*data, error)) { + return false; + } + return true; +} + +util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>&& wallet, WalletContext& context) +{ + MigrationResult res; + bilingual_str error; + std::vector<bilingual_str> warnings; + + // Make a backup of the DB + std::string wallet_name = wallet->GetName(); + fs::path this_wallet_dir = fs::absolute(fs::PathFromString(wallet->GetDatabase().Filename())).parent_path(); + fs::path backup_filename = fs::PathFromString(strprintf("%s-%d.legacy.bak", wallet_name, GetTime())); + fs::path backup_path = this_wallet_dir / backup_filename; + if (!wallet->BackupWallet(fs::PathToString(backup_path))) { + return util::Error{_("Error: Unable to make a backup of your wallet")}; + } + res.backup_path = backup_path; + + // Unload the wallet so that nothing else tries to use it while we're changing it + if (!RemoveWallet(context, wallet, /*load_on_start=*/std::nullopt, warnings)) { + return util::Error{_("Unable to unload the wallet before migrating")}; + } + UnloadWallet(std::move(wallet)); + + // Load the wallet but only in the context of this function. + // No signals should be connected nor should anything else be aware of this wallet + WalletContext empty_context; + empty_context.args = context.args; + DatabaseOptions options; + options.require_existing = true; + DatabaseStatus status; + std::unique_ptr<WalletDatabase> database = MakeWalletDatabase(wallet_name, options, status, error); + if (!database) { + return util::Error{Untranslated("Wallet file verification failed.") + Untranslated(" ") + error}; + } + + std::shared_ptr<CWallet> local_wallet = CWallet::Create(empty_context, wallet_name, std::move(database), options.create_flags, error, warnings); + if (!local_wallet) { + return util::Error{Untranslated("Wallet loading failed.") + Untranslated(" ") + error}; + } + + bool success = false; + { + LOCK(local_wallet->cs_wallet); + + // First change to using SQLite + if (!local_wallet->MigrateToSQLite(error)) return util::Error{error}; + + // Do the migration, and cleanup if it fails + success = DoMigration(*local_wallet, context, error, res); + } + + if (success) { + // Migration successful, unload the wallet locally, then reload it. + assert(local_wallet.use_count() == 1); + local_wallet.reset(); + LoadWallet(context, wallet_name, /*load_on_start=*/std::nullopt, options, status, error, warnings); + res.wallet_name = wallet_name; + } else { + // Migration failed, cleanup + // Copy the backup to the actual wallet dir + fs::path temp_backup_location = fsbridge::AbsPathJoin(GetWalletDir(), backup_filename); + fs::copy_file(backup_path, temp_backup_location, fs::copy_options::none); + + // Remember this wallet's walletdir to remove after unloading + std::vector<fs::path> wallet_dirs; + wallet_dirs.push_back(fs::PathFromString(local_wallet->GetDatabase().Filename()).parent_path()); + + // Unload the wallet locally + assert(local_wallet.use_count() == 1); + local_wallet.reset(); + + // Make list of wallets to cleanup + std::vector<std::shared_ptr<CWallet>> created_wallets; + created_wallets.push_back(std::move(res.watchonly_wallet)); + created_wallets.push_back(std::move(res.solvables_wallet)); + + // Get the directories to remove after unloading + for (std::shared_ptr<CWallet>& w : created_wallets) { + wallet_dirs.push_back(fs::PathFromString(w->GetDatabase().Filename()).parent_path()); + } + + // Unload the wallets + for (std::shared_ptr<CWallet>& w : created_wallets) { + if (!RemoveWallet(context, w, /*load_on_start=*/false)) { + error += _("\nUnable to cleanup failed migration"); + return util::Error{error}; + } + UnloadWallet(std::move(w)); + } + + // Delete the wallet directories + for (fs::path& dir : wallet_dirs) { + fs::remove_all(dir); + } + + // Restore the backup + DatabaseStatus status; + std::vector<bilingual_str> warnings; + if (!RestoreWallet(context, temp_backup_location, wallet_name, /*load_on_start=*/std::nullopt, status, error, warnings)) { + error += _("\nUnable to restore backup of wallet."); + return util::Error{error}; + } + + // Move the backup to the wallet dir + fs::copy_file(temp_backup_location, backup_path, fs::copy_options::none); + fs::remove(temp_backup_location); + + return util::Error{error}; + } + return res; +} } // namespace wallet diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 9281045c21..dc148512f8 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -316,7 +316,7 @@ private: std::string m_name; /** Internal database handle. */ - std::unique_ptr<WalletDatabase> const m_database; + std::unique_ptr<WalletDatabase> m_database; /** * The following is used to keep track of how far behind the wallet is @@ -907,6 +907,7 @@ public: void DeactivateScriptPubKeyMan(uint256 id, OutputType type, bool internal); //! Create new DescriptorScriptPubKeyMans and add them to the wallet + void SetupDescriptorScriptPubKeyMans(const CExtKey& master_key) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); void SetupDescriptorScriptPubKeyMans() EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); //! Return the DescriptorScriptPubKeyMan for a WalletDescriptor if it is already in the wallet @@ -919,6 +920,20 @@ public: //! Add a descriptor to the wallet, return a ScriptPubKeyMan & associated output type ScriptPubKeyMan* AddWalletDescriptor(WalletDescriptor& desc, const FlatSigningProvider& signing_provider, const std::string& label, bool internal) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + + /** Move all records from the BDB database to a new SQLite database for storage. + * The original BDB file will be deleted and replaced with a new SQLite file. + * A backup is not created. + * May crash if something unexpected happens in the filesystem. + */ + bool MigrateToSQLite(bilingual_str& error) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + + //! Get all of the descriptors from a legacy wallet + std::optional<MigrationData> GetDescriptorsForLegacy(bilingual_str& error) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + + //! Adds the ScriptPubKeyMans given in MigrationData to this wallet, removes LegacyScriptPubKeyMan, + //! and where needed, moves tx and address book entries to watchonly_wallet or solvable_wallet + bool ApplyMigrationData(MigrationData& data, bilingual_str& error) EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); }; /** @@ -977,6 +992,16 @@ bool RemoveWalletSetting(interfaces::Chain& chain, const std::string& wallet_nam bool DummySignInput(const SigningProvider& provider, CTxIn &tx_in, const CTxOut &txout, const CCoinControl* coin_control = nullptr); bool FillInputToWeight(CTxIn& txin, int64_t target_weight); + +struct MigrationResult { + std::string wallet_name; + std::shared_ptr<CWallet> watchonly_wallet; + std::shared_ptr<CWallet> solvables_wallet; + fs::path backup_path; +}; + +//! Do all steps to migrate a legacy wallet to a descriptor wallet +util::Result<MigrationResult> MigrateLegacyToDescriptor(std::shared_ptr<CWallet>&& wallet, WalletContext& context); } // namespace wallet #endif // BITCOIN_WALLET_WALLET_H diff --git a/src/wallet/walletdb.cpp b/src/wallet/walletdb.cpp index 0d85652c0c..30406a22f9 100644 --- a/src/wallet/walletdb.cpp +++ b/src/wallet/walletdb.cpp @@ -59,6 +59,7 @@ const std::string WALLETDESCRIPTORCKEY{"walletdescriptorckey"}; const std::string WALLETDESCRIPTORKEY{"walletdescriptorkey"}; const std::string WATCHMETA{"watchmeta"}; const std::string WATCHS{"watchs"}; +const std::unordered_set<std::string> LEGACY_TYPES{CRYPTED_KEY, CSCRIPT, DEFAULTKEY, HDCHAIN, KEYMETA, KEY, OLD_KEY, POOL, WATCHMETA, WATCHS}; } // namespace DBKeys // @@ -1083,6 +1084,45 @@ bool WalletBatch::WriteWalletFlags(const uint64_t flags) return WriteIC(DBKeys::FLAGS, flags); } +bool WalletBatch::EraseRecords(const std::unordered_set<std::string>& types) +{ + // Get cursor + if (!m_batch->StartCursor()) + { + return false; + } + + // Iterate the DB and look for any records that have the type prefixes + while (true) + { + // Read next record + CDataStream key(SER_DISK, CLIENT_VERSION); + CDataStream value(SER_DISK, CLIENT_VERSION); + bool complete; + bool ret = m_batch->ReadAtCursor(key, value, complete); + if (complete) { + break; + } + else if (!ret) + { + m_batch->CloseCursor(); + return false; + } + + // Make a copy of key to avoid data being deleted by the following read of the type + Span<const unsigned char> key_data = MakeUCharSpan(key); + + std::string type; + key >> type; + + if (types.count(type) > 0) { + m_batch->Erase(key_data); + } + } + m_batch->CloseCursor(); + return true; +} + bool WalletBatch::TxnBegin() { return m_batch->TxnBegin(); diff --git a/src/wallet/walletdb.h b/src/wallet/walletdb.h index a04ea598b6..6aa25fae03 100644 --- a/src/wallet/walletdb.h +++ b/src/wallet/walletdb.h @@ -84,6 +84,9 @@ extern const std::string WALLETDESCRIPTORCKEY; extern const std::string WALLETDESCRIPTORKEY; extern const std::string WATCHMETA; extern const std::string WATCHS; + +// Keys in this set pertain only to the legacy wallet (LegacyScriptPubKeyMan) and are removed during migration from legacy to descriptors. +extern const std::unordered_set<std::string> LEGACY_TYPES; } // namespace DBKeys /* simple HD chain data model */ @@ -276,6 +279,9 @@ public: //! write the hdchain model (external chain child index counter) bool WriteHDChain(const CHDChain& chain); + //! Delete records of the given types + bool EraseRecords(const std::unordered_set<std::string>& types); + bool WriteWalletFlags(const uint64_t flags); //! Begin a new transaction bool TxnBegin(); diff --git a/src/wallet/walletutil.h b/src/wallet/walletutil.h index 788d41ceb7..8434d64fb5 100644 --- a/src/wallet/walletutil.h +++ b/src/wallet/walletutil.h @@ -104,6 +104,20 @@ public: WalletDescriptor() {} WalletDescriptor(std::shared_ptr<Descriptor> descriptor, uint64_t creation_time, int32_t range_start, int32_t range_end, int32_t next_index) : descriptor(descriptor), creation_time(creation_time), range_start(range_start), range_end(range_end), next_index(next_index) {} }; + +class CWallet; +class DescriptorScriptPubKeyMan; + +/** struct containing information needed for migrating legacy wallets to descriptor wallets */ +struct MigrationData +{ + CExtKey master_key; + std::vector<std::pair<std::string, int64_t>> watch_descs; + std::vector<std::pair<std::string, int64_t>> solvable_descs; + std::vector<std::unique_ptr<DescriptorScriptPubKeyMan>> desc_spkms; + std::shared_ptr<CWallet> watchonly_wallet{nullptr}; + std::shared_ptr<CWallet> solvable_wallet{nullptr}; +}; } // namespace wallet #endif // BITCOIN_WALLET_WALLETUTIL_H |